{
    "file_diffs": [
        {
            "old_file_content": "#!/usr/bin/env python\n#\n# Copyright 2009 Facebook\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n# not use this file except in compliance with the License. You may obtain\n# a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n# License for the specific language governing permissions and limitations\n# under the License.\n\n\"\"\"Utility classes to write to and read from non-blocking files and sockets.\n\nContents:\n\n* `BaseIOStream`: Generic interface for reading and writing.\n* `IOStream`: Implementation of BaseIOStream using non-blocking sockets.\n* `SSLIOStream`: SSL-aware version of IOStream.\n* `PipeIOStream`: Pipe-based IOStream implementation.\n\"\"\"\n\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nimport collections\nimport errno\nimport numbers\nimport os\nimport socket\nimport ssl\nimport sys\nimport re\n\nfrom tornado.concurrent import TracebackFuture\nfrom tornado import ioloop\nfrom tornado.log import gen_log, app_log\nfrom tornado.netutil import ssl_wrap_socket, ssl_match_hostname, SSLCertificateError\nfrom tornado import stack_context\nfrom tornado.util import bytes_type\n\ntry:\n    from tornado.platform.posix import _set_nonblocking\nexcept ImportError:\n    _set_nonblocking = None\n\n# These errnos indicate that a non-blocking operation must be retried\n# at a later time.  On most platforms they're the same value, but on\n# some they differ.\n_ERRNO_WOULDBLOCK = (errno.EWOULDBLOCK, errno.EAGAIN)\n\n# These errnos indicate that a connection has been abruptly terminated.\n# They should be caught and handled less noisily than other errors.\n_ERRNO_CONNRESET = (errno.ECONNRESET, errno.ECONNABORTED, errno.EPIPE)\n\n\nclass StreamClosedError(IOError):\n    \"\"\"Exception raised by `IOStream` methods when the stream is closed.\n\n    Note that the close callback is scheduled to run *after* other\n    callbacks on the stream (to allow for buffered data to be processed),\n    so you may see this error before you see the close callback.\n    \"\"\"\n    pass\n\n\nclass BaseIOStream(object):\n    \"\"\"A utility class to write to and read from a non-blocking file or socket.\n\n    We support a non-blocking ``write()`` and a family of ``read_*()`` methods.\n    All of the methods take callbacks (since writing and reading are\n    non-blocking and asynchronous).\n\n    When a stream is closed due to an error, the IOStream's ``error``\n    attribute contains the exception object.\n\n    Subclasses must implement `fileno`, `close_fd`, `write_to_fd`,\n    `read_from_fd`, and optionally `get_fd_error`.\n    \"\"\"\n    def __init__(self, io_loop=None, max_buffer_size=None,\n                 read_chunk_size=4096):\n        self.io_loop = io_loop or ioloop.IOLoop.current()\n        self.max_buffer_size = max_buffer_size or 104857600\n        self.read_chunk_size = read_chunk_size\n        self.error = None\n        self._read_buffer = collections.deque()\n        self._write_buffer = collections.deque()\n        self._read_buffer_size = 0\n        self._write_buffer_frozen = False\n        self._read_delimiter = None\n        self._read_regex = None\n        self._read_bytes = None\n        self._read_until_close = False\n        self._read_callback = None\n        self._read_future = None\n        self._streaming_callback = None\n        self._write_callback = None\n        self._write_future = None\n        self._close_callback = None\n        self._connect_callback = None\n        self._connect_future = None\n        self._connecting = False\n        self._state = None\n        self._pending_callbacks = 0\n        self._closed = False\n\n    def fileno(self):\n        \"\"\"Returns the file descriptor for this stream.\"\"\"\n        raise NotImplementedError()\n\n    def close_fd(self):\n        \"\"\"Closes the file underlying this stream.\n\n        ``close_fd`` is called by `BaseIOStream` and should not be called\n        elsewhere; other users should call `close` instead.\n        \"\"\"\n        raise NotImplementedError()\n\n    def write_to_fd(self, data):\n        \"\"\"Attempts to write ``data`` to the underlying file.\n\n        Returns the number of bytes written.\n        \"\"\"\n        raise NotImplementedError()\n\n    def read_from_fd(self):\n        \"\"\"Attempts to read from the underlying file.\n\n        Returns ``None`` if there was nothing to read (the socket\n        returned `~errno.EWOULDBLOCK` or equivalent), otherwise\n        returns the data.  When possible, should return no more than\n        ``self.read_chunk_size`` bytes at a time.\n        \"\"\"\n        raise NotImplementedError()\n\n    def get_fd_error(self):\n        \"\"\"Returns information about any error on the underlying file.\n\n        This method is called after the `.IOLoop` has signaled an error on the\n        file descriptor, and should return an Exception (such as `socket.error`\n        with additional information, or None if no such information is\n        available.\n        \"\"\"\n        return None\n\n    def read_until_regex(self, regex, callback=None):\n        \"\"\"Run ``callback`` when we read the given regex pattern.\n\n        The callback will get the data read (including the data that\n        matched the regex and anything that came before it) as an argument.\n        \"\"\"\n        future = self._set_read_callback(callback)\n        self._read_regex = re.compile(regex)\n        self._try_inline_read()\n        return future\n\n    def read_until(self, delimiter, callback=None):\n        \"\"\"Run ``callback`` when we read the given delimiter.\n\n        The callback will get the data read (including the delimiter)\n        as an argument.\n        \"\"\"\n        future = self._set_read_callback(callback)\n        self._read_delimiter = delimiter\n        self._try_inline_read()\n        return future\n\n    def read_bytes(self, num_bytes, callback=None, streaming_callback=None):\n        \"\"\"Run callback when we read the given number of bytes.\n\n        If a ``streaming_callback`` is given, it will be called with chunks\n        of data as they become available, and the argument to the final\n        ``callback`` will be empty.  Otherwise, the ``callback`` gets\n        the data as an argument.\n        \"\"\"\n        future = self._set_read_callback(callback)\n        assert isinstance(num_bytes, numbers.Integral)\n        self._read_bytes = num_bytes\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        self._try_inline_read()\n        return future\n\n    def read_until_close(self, callback=None, streaming_callback=None):\n        \"\"\"Reads all data from the socket until it is closed.\n\n        If a ``streaming_callback`` is given, it will be called with chunks\n        of data as they become available, and the argument to the final\n        ``callback`` will be empty.  Otherwise, the ``callback`` gets the\n        data as an argument.\n\n        Subject to ``max_buffer_size`` limit from `IOStream` constructor if\n        a ``streaming_callback`` is not used.\n        \"\"\"\n        future = self._set_read_callback(callback)\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        if self.closed():\n            if self._streaming_callback is not None:\n                self._run_callback(self._streaming_callback,\n                                   self._consume(self._read_buffer_size))\n            self._run_read_callback(self._consume(self._read_buffer_size))\n            return future\n        self._read_until_close = True\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        self._try_inline_read()\n        return future\n\n    def write(self, data, callback=None):\n        \"\"\"Write the given data to this stream.\n\n        If ``callback`` is given, we call it when all of the buffered write\n        data has been successfully written to the stream. If there was\n        previously buffered write data and an old write callback, that\n        callback is simply overwritten with this new callback.\n        \"\"\"\n        assert isinstance(data, bytes_type)\n        self._check_closed()\n        # We use bool(_write_buffer) as a proxy for write_buffer_size>0,\n        # so never put empty strings in the buffer.\n        if data:\n            # Break up large contiguous strings before inserting them in the\n            # write buffer, so we don't have to recopy the entire thing\n            # as we slice off pieces to send to the socket.\n            WRITE_BUFFER_CHUNK_SIZE = 128 * 1024\n            for i in range(0, len(data), WRITE_BUFFER_CHUNK_SIZE):\n                self._write_buffer.append(data[i:i + WRITE_BUFFER_CHUNK_SIZE])\n        if callback is not None:\n            self._write_callback = stack_context.wrap(callback)\n            future = None\n        else:\n            future = self._write_future = TracebackFuture()\n        if not self._connecting:\n            self._handle_write()\n            if self._write_buffer:\n                self._add_io_state(self.io_loop.WRITE)\n            self._maybe_add_error_listener()\n        return future\n\n    def set_close_callback(self, callback):\n        \"\"\"Call the given callback when the stream is closed.\"\"\"\n        self._close_callback = stack_context.wrap(callback)\n\n    def close(self, exc_info=False):\n        \"\"\"Close this stream.\n\n        If ``exc_info`` is true, set the ``error`` attribute to the current\n        exception from `sys.exc_info` (or if ``exc_info`` is a tuple,\n        use that instead of `sys.exc_info`).\n        \"\"\"\n        if not self.closed():\n            if exc_info:\n                if not isinstance(exc_info, tuple):\n                    exc_info = sys.exc_info()\n                if any(exc_info):\n                    self.error = exc_info[1]\n            if self._read_until_close:\n                if (self._streaming_callback is not None and\n                        self._read_buffer_size):\n                    self._run_callback(self._streaming_callback,\n                                       self._consume(self._read_buffer_size))\n                self._read_until_close = False\n                self._run_read_callback(self._consume(self._read_buffer_size))\n            if self._state is not None:\n                self.io_loop.remove_handler(self.fileno())\n                self._state = None\n            self.close_fd()\n            self._closed = True\n        self._maybe_run_close_callback()\n\n    def _maybe_run_close_callback(self):\n        # If there are pending callbacks, don't run the close callback\n        # until they're done (see _maybe_add_error_handler)\n        if self.closed() and self._pending_callbacks == 0:\n            futures = []\n            if self._read_future is not None:\n                futures.append(self._read_future)\n                self._read_future = None\n            if self._write_future is not None:\n                futures.append(self._write_future)\n                self._write_future = None\n            if self._connect_future is not None:\n                futures.append(self._connect_future)\n                self._connect_future = None\n            for future in futures:\n                future.set_exception(StreamClosedError())\n            if self._close_callback is not None:\n                cb = self._close_callback\n                self._close_callback = None\n                self._run_callback(cb)\n            # Delete any unfinished callbacks to break up reference cycles.\n            self._read_callback = self._write_callback = None\n            # Clear the buffers so they can be cleared immediately even\n            # if the IOStream object is kept alive by a reference cycle.\n            # TODO: Clear the read buffer too; it currently breaks some tests.\n            self._write_buffer = None\n\n    def reading(self):\n        \"\"\"Returns true if we are currently reading from the stream.\"\"\"\n        return self._read_callback is not None\n\n    def writing(self):\n        \"\"\"Returns true if we are currently writing to the stream.\"\"\"\n        return bool(self._write_buffer)\n\n    def closed(self):\n        \"\"\"Returns true if the stream has been closed.\"\"\"\n        return self._closed\n\n    def set_nodelay(self, value):\n        \"\"\"Sets the no-delay flag for this stream.\n\n        By default, data written to TCP streams may be held for a time\n        to make the most efficient use of bandwidth (according to\n        Nagle's algorithm).  The no-delay flag requests that data be\n        written as soon as possible, even if doing so would consume\n        additional bandwidth.\n\n        This flag is currently defined only for TCP-based ``IOStreams``.\n\n        .. versionadded:: 3.1\n        \"\"\"\n        pass\n\n    def _handle_events(self, fd, events):\n        if self.closed():\n            gen_log.warning(\"Got events for closed stream %s\", fd)\n            return\n        try:\n            if events & self.io_loop.READ:\n                self._handle_read()\n            if self.closed():\n                return\n            if events & self.io_loop.WRITE:\n                if self._connecting:\n                    self._handle_connect()\n                self._handle_write()\n            if self.closed():\n                return\n            if events & self.io_loop.ERROR:\n                self.error = self.get_fd_error()\n                # We may have queued up a user callback in _handle_read or\n                # _handle_write, so don't close the IOStream until those\n                # callbacks have had a chance to run.\n                self.io_loop.add_callback(self.close)\n                return\n            state = self.io_loop.ERROR\n            if self.reading():\n                state |= self.io_loop.READ\n            if self.writing():\n                state |= self.io_loop.WRITE\n            if state == self.io_loop.ERROR:\n                state |= self.io_loop.READ\n            if state != self._state:\n                assert self._state is not None, \\\n                    \"shouldn't happen: _handle_events without self._state\"\n                self._state = state\n                self.io_loop.update_handler(self.fileno(), self._state)\n        except Exception:\n            gen_log.error(\"Uncaught exception, closing connection.\",\n                          exc_info=True)\n            self.close(exc_info=True)\n            raise\n\n    def _run_callback(self, callback, *args):\n        def wrapper():\n            self._pending_callbacks -= 1\n            try:\n                callback(*args)\n            except Exception:\n                app_log.error(\"Uncaught exception, closing connection.\",\n                              exc_info=True)\n                # Close the socket on an uncaught exception from a user callback\n                # (It would eventually get closed when the socket object is\n                # gc'd, but we don't want to rely on gc happening before we\n                # run out of file descriptors)\n                self.close(exc_info=True)\n                # Re-raise the exception so that IOLoop.handle_callback_exception\n                # can see it and log the error\n                raise\n            self._maybe_add_error_listener()\n        # We schedule callbacks to be run on the next IOLoop iteration\n        # rather than running them directly for several reasons:\n        # * Prevents unbounded stack growth when a callback calls an\n        #   IOLoop operation that immediately runs another callback\n        # * Provides a predictable execution context for e.g.\n        #   non-reentrant mutexes\n        # * Ensures that the try/except in wrapper() is run outside\n        #   of the application's StackContexts\n        with stack_context.NullContext():\n            # stack_context was already captured in callback, we don't need to\n            # capture it again for IOStream's wrapper.  This is especially\n            # important if the callback was pre-wrapped before entry to\n            # IOStream (as in HTTPConnection._header_callback), as we could\n            # capture and leak the wrong context here.\n            self._pending_callbacks += 1\n            self.io_loop.add_callback(wrapper)\n\n    def _handle_read(self):\n        try:\n            try:\n                # Pretend to have a pending callback so that an EOF in\n                # _read_to_buffer doesn't trigger an immediate close\n                # callback.  At the end of this method we'll either\n                # estabilsh a real pending callback via\n                # _read_from_buffer or run the close callback.\n                #\n                # We need two try statements here so that\n                # pending_callbacks is decremented before the `except`\n                # clause below (which calls `close` and does need to\n                # trigger the callback)\n                self._pending_callbacks += 1\n                while not self.closed():\n                    # Read from the socket until we get EWOULDBLOCK or equivalent.\n                    # SSL sockets do some internal buffering, and if the data is\n                    # sitting in the SSL object's buffer select() and friends\n                    # can't see it; the only way to find out if it's there is to\n                    # try to read it.\n                    if self._read_to_buffer() == 0:\n                        break\n            finally:\n                self._pending_callbacks -= 1\n        except Exception:\n            gen_log.warning(\"error on read\", exc_info=True)\n            self.close(exc_info=True)\n            return\n        if self._read_from_buffer():\n            return\n        else:\n            self._maybe_run_close_callback()\n\n    def _set_read_callback(self, callback):\n        assert self._read_callback is None, \"Already reading\"\n        assert self._read_future is None, \"Already reading\"\n        if callback is not None:\n            self._read_callback = stack_context.wrap(callback)\n        else:\n            self._read_future = TracebackFuture()\n        return self._read_future\n\n    def _run_read_callback(self, data):\n        self._streaming_callback = None\n        if self._read_future is not None:\n            future = self._read_future\n            self._read_future = None\n            future.set_result(data)\n        if self._read_callback is not None:\n            callback = self._read_callback\n            self._read_callback = None\n            self._run_callback(callback, data)\n\n    def _try_inline_read(self):\n        \"\"\"Attempt to complete the current read operation from buffered data.\n\n        If the read can be completed without blocking, schedules the\n        read callback on the next IOLoop iteration; otherwise starts\n        listening for reads on the socket.\n        \"\"\"\n        # See if we've already got the data from a previous read\n        if self._read_from_buffer():\n            return\n        self._check_closed()\n        try:\n            try:\n                # See comments in _handle_read about incrementing _pending_callbacks\n                self._pending_callbacks += 1\n                while not self.closed():\n                    if self._read_to_buffer() == 0:\n                        break\n            finally:\n                self._pending_callbacks -= 1\n        except Exception:\n            # If there was an in _read_to_buffer, we called close() already,\n            # but couldn't run the close callback because of _pending_callbacks.\n            # Before we escape from this function, run the close callback if\n            # applicable.\n            self._maybe_run_close_callback()\n            raise\n        if self._read_from_buffer():\n            return\n        self._maybe_add_error_listener()\n\n    def _read_to_buffer(self):\n        \"\"\"Reads from the socket and appends the result to the read buffer.\n\n        Returns the number of bytes read.  Returns 0 if there is nothing\n        to read (i.e. the read returns EWOULDBLOCK or equivalent).  On\n        error closes the socket and raises an exception.\n        \"\"\"\n        try:\n            chunk = self.read_from_fd()\n        except (socket.error, IOError, OSError) as e:\n            # ssl.SSLError is a subclass of socket.error\n            if e.args[0] in _ERRNO_CONNRESET:\n                # Treat ECONNRESET as a connection close rather than\n                # an error to minimize log spam  (the exception will\n                # be available on self.error for apps that care).\n                self.close(exc_info=True)\n                return\n            self.close(exc_info=True)\n            raise\n        if chunk is None:\n            return 0\n        self._read_buffer.append(chunk)\n        self._read_buffer_size += len(chunk)\n        if self._read_buffer_size >= self.max_buffer_size:\n            gen_log.error(\"Reached maximum read buffer size\")\n            self.close()\n            raise IOError(\"Reached maximum read buffer size\")\n        return len(chunk)\n\n    def _read_from_buffer(self):\n        \"\"\"Attempts to complete the currently-pending read from the buffer.\n\n        Returns True if the read was completed.\n        \"\"\"\n        if self._streaming_callback is not None and self._read_buffer_size:\n            bytes_to_consume = self._read_buffer_size\n            if self._read_bytes is not None:\n                bytes_to_consume = min(self._read_bytes, bytes_to_consume)\n                self._read_bytes -= bytes_to_consume\n            self._run_callback(self._streaming_callback,\n                               self._consume(bytes_to_consume))\n        if self._read_bytes is not None and self._read_buffer_size >= self._read_bytes:\n            num_bytes = self._read_bytes\n            self._read_bytes = None\n            self._run_read_callback(self._consume(num_bytes))\n            return True\n        elif self._read_delimiter is not None:\n            # Multi-byte delimiters (e.g. '\\r\\n') may straddle two\n            # chunks in the read buffer, so we can't easily find them\n            # without collapsing the buffer.  However, since protocols\n            # using delimited reads (as opposed to reads of a known\n            # length) tend to be \"line\" oriented, the delimiter is likely\n            # to be in the first few chunks.  Merge the buffer gradually\n            # since large merges are relatively expensive and get undone in\n            # consume().\n            if self._read_buffer:\n                while True:\n                    loc = self._read_buffer[0].find(self._read_delimiter)\n                    if loc != -1:\n                        delimiter_len = len(self._read_delimiter)\n                        self._read_delimiter = None\n                        self._run_read_callback(\n                            self._consume(loc + delimiter_len))\n                        return True\n                    if len(self._read_buffer) == 1:\n                        break\n                    _double_prefix(self._read_buffer)\n        elif self._read_regex is not None:\n            if self._read_buffer:\n                while True:\n                    m = self._read_regex.search(self._read_buffer[0])\n                    if m is not None:\n                        self._read_regex = None\n                        self._run_read_callback(self._consume(m.end()))\n                        return True\n                    if len(self._read_buffer) == 1:\n                        break\n                    _double_prefix(self._read_buffer)\n        return False\n\n    def _handle_write(self):\n        while self._write_buffer:\n            try:\n                if not self._write_buffer_frozen:\n                    # On windows, socket.send blows up if given a\n                    # write buffer that's too large, instead of just\n                    # returning the number of bytes it was able to\n                    # process.  Therefore we must not call socket.send\n                    # with more than 128KB at a time.\n                    _merge_prefix(self._write_buffer, 128 * 1024)\n                num_bytes = self.write_to_fd(self._write_buffer[0])\n                if num_bytes == 0:\n                    # With OpenSSL, if we couldn't write the entire buffer,\n                    # the very same string object must be used on the\n                    # next call to send.  Therefore we suppress\n                    # merging the write buffer after an incomplete send.\n                    # A cleaner solution would be to set\n                    # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, but this is\n                    # not yet accessible from python\n                    # (http://bugs.python.org/issue8240)\n                    self._write_buffer_frozen = True\n                    break\n                self._write_buffer_frozen = False\n                _merge_prefix(self._write_buffer, num_bytes)\n                self._write_buffer.popleft()\n            except (socket.error, IOError, OSError) as e:\n                if e.args[0] in _ERRNO_WOULDBLOCK:\n                    self._write_buffer_frozen = True\n                    break\n                else:\n                    if e.args[0] not in _ERRNO_CONNRESET:\n                        # Broken pipe errors are usually caused by connection\n                        # reset, and its better to not log EPIPE errors to\n                        # minimize log spam\n                        gen_log.warning(\"Write error on %s: %s\",\n                                        self.fileno(), e)\n                    self.close(exc_info=True)\n                    return\n        if not self._write_buffer:\n            if self._write_callback:\n                callback = self._write_callback\n                self._write_callback = None\n                self._run_callback(callback)\n            if self._write_future:\n                future = self._write_future\n                self._write_future = None\n                future.set_result(None)\n\n    def _consume(self, loc):\n        if loc == 0:\n            return b\"\"\n        _merge_prefix(self._read_buffer, loc)\n        self._read_buffer_size -= loc\n        return self._read_buffer.popleft()\n\n    def _check_closed(self):\n        if self.closed():\n            raise StreamClosedError(\"Stream is closed\")\n\n    def _maybe_add_error_listener(self):\n        if self._state is None and self._pending_callbacks == 0:\n            if self.closed():\n                self._maybe_run_close_callback()\n            else:\n                self._add_io_state(ioloop.IOLoop.READ)\n\n    def _add_io_state(self, state):\n        \"\"\"Adds `state` (IOLoop.{READ,WRITE} flags) to our event handler.\n\n        Implementation notes: Reads and writes have a fast path and a\n        slow path.  The fast path reads synchronously from socket\n        buffers, while the slow path uses `_add_io_state` to schedule\n        an IOLoop callback.  Note that in both cases, the callback is\n        run asynchronously with `_run_callback`.\n\n        To detect closed connections, we must have called\n        `_add_io_state` at some point, but we want to delay this as\n        much as possible so we don't have to set an `IOLoop.ERROR`\n        listener that will be overwritten by the next slow-path\n        operation.  As long as there are callbacks scheduled for\n        fast-path ops, those callbacks may do more reads.\n        If a sequence of fast-path ops do not end in a slow-path op,\n        (e.g. for an @asynchronous long-poll request), we must add\n        the error handler.  This is done in `_run_callback` and `write`\n        (since the write callback is optional so we can have a\n        fast-path write with no `_run_callback`)\n        \"\"\"\n        if self.closed():\n            # connection has been closed, so there can be no future events\n            return\n        if self._state is None:\n            self._state = ioloop.IOLoop.ERROR | state\n            with stack_context.NullContext():\n                self.io_loop.add_handler(\n                    self.fileno(), self._handle_events, self._state)\n        elif not self._state & state:\n            self._state = self._state | state\n            self.io_loop.update_handler(self.fileno(), self._state)\n\n\nclass IOStream(BaseIOStream):\n    r\"\"\"Socket-based `IOStream` implementation.\n\n    This class supports the read and write methods from `BaseIOStream`\n    plus a `connect` method.\n\n    The ``socket`` parameter may either be connected or unconnected.\n    For server operations the socket is the result of calling\n    `socket.accept <socket.socket.accept>`.  For client operations the\n    socket is created with `socket.socket`, and may either be\n    connected before passing it to the `IOStream` or connected with\n    `IOStream.connect`.\n\n    A very simple (and broken) HTTP client using this class::\n\n        import tornado.ioloop\n        import tornado.iostream\n        import socket\n\n        def send_request():\n            stream.write(b\"GET / HTTP/1.0\\r\\nHost: friendfeed.com\\r\\n\\r\\n\")\n            stream.read_until(b\"\\r\\n\\r\\n\", on_headers)\n\n        def on_headers(data):\n            headers = {}\n            for line in data.split(b\"\\r\\n\"):\n               parts = line.split(b\":\")\n               if len(parts) == 2:\n                   headers[parts[0].strip()] = parts[1].strip()\n            stream.read_bytes(int(headers[b\"Content-Length\"]), on_body)\n\n        def on_body(data):\n            print data\n            stream.close()\n            tornado.ioloop.IOLoop.instance().stop()\n\n        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)\n        stream = tornado.iostream.IOStream(s)\n        stream.connect((\"friendfeed.com\", 80), send_request)\n        tornado.ioloop.IOLoop.instance().start()\n    \"\"\"\n    def __init__(self, socket, *args, **kwargs):\n        self.socket = socket\n        self.socket.setblocking(False)\n        super(IOStream, self).__init__(*args, **kwargs)\n\n    def fileno(self):\n        return self.socket\n\n    def close_fd(self):\n        self.socket.close()\n        self.socket = None\n\n    def get_fd_error(self):\n        errno = self.socket.getsockopt(socket.SOL_SOCKET,\n                                       socket.SO_ERROR)\n        return socket.error(errno, os.strerror(errno))\n\n    def read_from_fd(self):\n        try:\n            chunk = self.socket.recv(self.read_chunk_size)\n        except socket.error as e:\n            if e.args[0] in _ERRNO_WOULDBLOCK:\n                return None\n            else:\n                raise\n        if not chunk:\n            self.close()\n            return None\n        return chunk\n\n    def write_to_fd(self, data):\n        return self.socket.send(data)\n\n    def connect(self, address, callback=None, server_hostname=None):\n        \"\"\"Connects the socket to a remote address without blocking.\n\n        May only be called if the socket passed to the constructor was\n        not previously connected.  The address parameter is in the\n        same format as for `socket.connect <socket.socket.connect>`,\n        i.e. a ``(host, port)`` tuple.  If ``callback`` is specified,\n        it will be called when the connection is completed.\n\n        If specified, the ``server_hostname`` parameter will be used\n        in SSL connections for certificate validation (if requested in\n        the ``ssl_options``) and SNI (if supported; requires\n        Python 3.2+).\n\n        Note that it is safe to call `IOStream.write\n        <BaseIOStream.write>` while the connection is pending, in\n        which case the data will be written as soon as the connection\n        is ready.  Calling `IOStream` read methods before the socket is\n        connected works on some platforms but is non-portable.\n        \"\"\"\n        self._connecting = True\n        try:\n            self.socket.connect(address)\n        except socket.error as e:\n            # In non-blocking mode we expect connect() to raise an\n            # exception with EINPROGRESS or EWOULDBLOCK.\n            #\n            # On freebsd, other errors such as ECONNREFUSED may be\n            # returned immediately when attempting to connect to\n            # localhost, so handle them the same way as an error\n            # reported later in _handle_connect.\n            if (e.args[0] != errno.EINPROGRESS and\n                    e.args[0] not in _ERRNO_WOULDBLOCK):\n                gen_log.warning(\"Connect error on fd %s: %s\",\n                                self.socket.fileno(), e)\n                self.close(exc_info=True)\n                return\n        if callback is not None:\n            self._connect_callback = stack_context.wrap(callback)\n            future = None\n        else:\n            future = self._connect_future = TracebackFuture()\n        self._add_io_state(self.io_loop.WRITE)\n        return future\n\n    def _handle_connect(self):\n        err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)\n        if err != 0:\n            self.error = socket.error(err, os.strerror(err))\n            # IOLoop implementations may vary: some of them return\n            # an error state before the socket becomes writable, so\n            # in that case a connection failure would be handled by the\n            # error path in _handle_events instead of here.\n            gen_log.warning(\"Connect error on fd %s: %s\",\n                            self.socket.fileno(), errno.errorcode[err])\n            self.close()\n            return\n        if self._connect_callback is not None:\n            callback = self._connect_callback\n            self._connect_callback = None\n            self._run_callback(callback)\n        if self._connect_future is not None:\n            future = self._connect_future\n            self._connect_future = None\n            future.set_result(None)\n        self._connecting = False\n\n    def set_nodelay(self, value):\n        if (self.socket is not None and\n                self.socket.family in (socket.AF_INET, socket.AF_INET6)):\n            try:\n                self.socket.setsockopt(socket.IPPROTO_TCP,\n                                       socket.TCP_NODELAY, 1 if value else 0)\n            except socket.error as e:\n                # Sometimes setsockopt will fail if the socket is closed\n                # at the wrong time.  This can happen with HTTPServer\n                # resetting the value to false between requests.\n                if e.errno not in (errno.EINVAL, errno.ECONNRESET):\n                    raise\n\n\nclass SSLIOStream(IOStream):\n    \"\"\"A utility class to write to and read from a non-blocking SSL socket.\n\n    If the socket passed to the constructor is already connected,\n    it should be wrapped with::\n\n        ssl.wrap_socket(sock, do_handshake_on_connect=False, **kwargs)\n\n    before constructing the `SSLIOStream`.  Unconnected sockets will be\n    wrapped when `IOStream.connect` is finished.\n    \"\"\"\n    def __init__(self, *args, **kwargs):\n        \"\"\"The ``ssl_options`` keyword argument may either be a dictionary\n        of keywords arguments for `ssl.wrap_socket`, or an `ssl.SSLContext`\n        object.\n        \"\"\"\n        self._ssl_options = kwargs.pop('ssl_options', {})\n        super(SSLIOStream, self).__init__(*args, **kwargs)\n        self._ssl_accepting = True\n        self._handshake_reading = False\n        self._handshake_writing = False\n        self._ssl_connect_callback = None\n        self._server_hostname = None\n\n        # If the socket is already connected, attempt to start the handshake.\n        try:\n            self.socket.getpeername()\n        except socket.error:\n            pass\n        else:\n            # Indirectly start the handshake, which will run on the next\n            # IOLoop iteration and then the real IO state will be set in\n            # _handle_events.\n            self._add_io_state(self.io_loop.WRITE)\n\n    def reading(self):\n        return self._handshake_reading or super(SSLIOStream, self).reading()\n\n    def writing(self):\n        return self._handshake_writing or super(SSLIOStream, self).writing()\n\n    def _do_ssl_handshake(self):\n        # Based on code from test_ssl.py in the python stdlib\n        try:\n            self._handshake_reading = False\n            self._handshake_writing = False\n            self.socket.do_handshake()\n        except ssl.SSLError as err:\n            if err.args[0] == ssl.SSL_ERROR_WANT_READ:\n                self._handshake_reading = True\n                return\n            elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:\n                self._handshake_writing = True\n                return\n            elif err.args[0] in (ssl.SSL_ERROR_EOF,\n                                 ssl.SSL_ERROR_ZERO_RETURN):\n                return self.close(exc_info=True)\n            elif err.args[0] == ssl.SSL_ERROR_SSL:\n                try:\n                    peer = self.socket.getpeername()\n                except Exception:\n                    peer = '(not connected)'\n                gen_log.warning(\"SSL Error on %s %s: %s\",\n                                self.socket.fileno(), peer, err)\n                return self.close(exc_info=True)\n            raise\n        except socket.error as err:\n            if err.args[0] in _ERRNO_CONNRESET:\n                return self.close(exc_info=True)\n        except AttributeError:\n            # On Linux, if the connection was reset before the call to\n            # wrap_socket, do_handshake will fail with an\n            # AttributeError.\n            return self.close(exc_info=True)\n        else:\n            self._ssl_accepting = False\n            if not self._verify_cert(self.socket.getpeercert()):\n                self.close()\n                return\n            if self._ssl_connect_callback is not None:\n                callback = self._ssl_connect_callback\n                self._ssl_connect_callback = None\n                self._run_callback(callback)\n\n    def _verify_cert(self, peercert):\n        \"\"\"Returns True if peercert is valid according to the configured\n        validation mode and hostname.\n\n        The ssl handshake already tested the certificate for a valid\n        CA signature; the only thing that remains is to check\n        the hostname.\n        \"\"\"\n        if isinstance(self._ssl_options, dict):\n            verify_mode = self._ssl_options.get('cert_reqs', ssl.CERT_NONE)\n        elif isinstance(self._ssl_options, ssl.SSLContext):\n            verify_mode = self._ssl_options.verify_mode\n        assert verify_mode in (ssl.CERT_NONE, ssl.CERT_REQUIRED, ssl.CERT_OPTIONAL)\n        if verify_mode == ssl.CERT_NONE or self._server_hostname is None:\n            return True\n        cert = self.socket.getpeercert()\n        if cert is None and verify_mode == ssl.CERT_REQUIRED:\n            gen_log.warning(\"No SSL certificate given\")\n            return False\n        try:\n            ssl_match_hostname(peercert, self._server_hostname)\n        except SSLCertificateError:\n            gen_log.warning(\"Invalid SSL certificate\", exc_info=True)\n            return False\n        else:\n            return True\n\n    def _handle_read(self):\n        if self._ssl_accepting:\n            self._do_ssl_handshake()\n            return\n        super(SSLIOStream, self)._handle_read()\n\n    def _handle_write(self):\n        if self._ssl_accepting:\n            self._do_ssl_handshake()\n            return\n        super(SSLIOStream, self)._handle_write()\n\n    def connect(self, address, callback=None, server_hostname=None):\n        # Save the user's callback and run it after the ssl handshake\n        # has completed.\n        self._ssl_connect_callback = stack_context.wrap(callback)\n        self._server_hostname = server_hostname\n        # Note: Since we don't pass our callback argument along to\n        # super.connect(), this will always return a Future.\n        # This is harmless, but a bit less efficient than it could be.\n        return super(SSLIOStream, self).connect(address, callback=None)\n\n    def _handle_connect(self):\n        # When the connection is complete, wrap the socket for SSL\n        # traffic.  Note that we do this by overriding _handle_connect\n        # instead of by passing a callback to super().connect because\n        # user callbacks are enqueued asynchronously on the IOLoop,\n        # but since _handle_events calls _handle_connect immediately\n        # followed by _handle_write we need this to be synchronous.\n        #\n        # The IOLoop will get confused if we swap out self.socket while the\n        # fd is registered, so remove it now and re-register after\n        # wrap_socket().\n        self.io_loop.remove_handler(self.socket)\n        old_state = self._state\n        self._state = None\n        self.socket = ssl_wrap_socket(self.socket, self._ssl_options,\n                                      server_hostname=self._server_hostname,\n                                      do_handshake_on_connect=False)\n        self._add_io_state(old_state)\n        super(SSLIOStream, self)._handle_connect()\n\n    def read_from_fd(self):\n        if self._ssl_accepting:\n            # If the handshake hasn't finished yet, there can't be anything\n            # to read (attempting to read may or may not raise an exception\n            # depending on the SSL version)\n            return None\n        try:\n            # SSLSocket objects have both a read() and recv() method,\n            # while regular sockets only have recv().\n            # The recv() method blocks (at least in python 2.6) if it is\n            # called when there is nothing to read, so we have to use\n            # read() instead.\n            chunk = self.socket.read(self.read_chunk_size)\n        except ssl.SSLError as e:\n            # SSLError is a subclass of socket.error, so this except\n            # block must come first.\n            if e.args[0] == ssl.SSL_ERROR_WANT_READ:\n                return None\n            else:\n                raise\n        except socket.error as e:\n            if e.args[0] in _ERRNO_WOULDBLOCK:\n                return None\n            else:\n                raise\n        if not chunk:\n            self.close()\n            return None\n        return chunk\n\n\nclass PipeIOStream(BaseIOStream):\n    \"\"\"Pipe-based `IOStream` implementation.\n\n    The constructor takes an integer file descriptor (such as one returned\n    by `os.pipe`) rather than an open file object.  Pipes are generally\n    one-way, so a `PipeIOStream` can be used for reading or writing but not\n    both.\n    \"\"\"\n    def __init__(self, fd, *args, **kwargs):\n        self.fd = fd\n        _set_nonblocking(fd)\n        super(PipeIOStream, self).__init__(*args, **kwargs)\n\n    def fileno(self):\n        return self.fd\n\n    def close_fd(self):\n        os.close(self.fd)\n\n    def write_to_fd(self, data):\n        return os.write(self.fd, data)\n\n    def read_from_fd(self):\n        try:\n            chunk = os.read(self.fd, self.read_chunk_size)\n        except (IOError, OSError) as e:\n            if e.args[0] in _ERRNO_WOULDBLOCK:\n                return None\n            elif e.args[0] == errno.EBADF:\n                # If the writing half of a pipe is closed, select will\n                # report it as readable but reads will fail with EBADF.\n                self.close(exc_info=True)\n                return None\n            else:\n                raise\n        if not chunk:\n            self.close()\n            return None\n        return chunk\n\n\ndef _double_prefix(deque):\n    \"\"\"Grow by doubling, but don't split the second chunk just because the\n    first one is small.\n    \"\"\"\n    new_len = max(len(deque[0]) * 2,\n                  (len(deque[0]) + len(deque[1])))\n    _merge_prefix(deque, new_len)\n\n\ndef _merge_prefix(deque, size):\n    \"\"\"Replace the first entries in a deque of strings with a single\n    string of up to size bytes.\n\n    >>> d = collections.deque(['abc', 'de', 'fghi', 'j'])\n    >>> _merge_prefix(d, 5); print(d)\n    deque(['abcde', 'fghi', 'j'])\n\n    Strings will be split as necessary to reach the desired size.\n    >>> _merge_prefix(d, 7); print(d)\n    deque(['abcdefg', 'hi', 'j'])\n\n    >>> _merge_prefix(d, 3); print(d)\n    deque(['abc', 'defg', 'hi', 'j'])\n\n    >>> _merge_prefix(d, 100); print(d)\n    deque(['abcdefghij'])\n    \"\"\"\n    if len(deque) == 1 and len(deque[0]) <= size:\n        return\n    prefix = []\n    remaining = size\n    while deque and remaining > 0:\n        chunk = deque.popleft()\n        if len(chunk) > remaining:\n            deque.appendleft(chunk[remaining:])\n            chunk = chunk[:remaining]\n        prefix.append(chunk)\n        remaining -= len(chunk)\n    # This data structure normally just contains byte strings, but\n    # the unittest gets messy if it doesn't use the default str() type,\n    # so do the merge based on the type of data that's actually present.\n    if prefix:\n        deque.appendleft(type(prefix[0])().join(prefix))\n    if not deque:\n        deque.appendleft(b\"\")\n\n\ndef doctests():\n    import doctest\n    return doctest.DocTestSuite()\n",
            "new_file_content": "#!/usr/bin/env python\n#\n# Copyright 2009 Facebook\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n# not use this file except in compliance with the License. You may obtain\n# a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n# License for the specific language governing permissions and limitations\n# under the License.\n\n\"\"\"Utility classes to write to and read from non-blocking files and sockets.\n\nContents:\n\n* `BaseIOStream`: Generic interface for reading and writing.\n* `IOStream`: Implementation of BaseIOStream using non-blocking sockets.\n* `SSLIOStream`: SSL-aware version of IOStream.\n* `PipeIOStream`: Pipe-based IOStream implementation.\n\"\"\"\n\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nimport collections\nimport errno\nimport numbers\nimport os\nimport socket\nimport ssl\nimport sys\nimport re\n\nfrom tornado.concurrent import TracebackFuture\nfrom tornado import ioloop\nfrom tornado.log import gen_log, app_log\nfrom tornado.netutil import ssl_wrap_socket, ssl_match_hostname, SSLCertificateError\nfrom tornado import stack_context\nfrom tornado.util import bytes_type\n\ntry:\n    from tornado.platform.posix import _set_nonblocking\nexcept ImportError:\n    _set_nonblocking = None\n\n# These errnos indicate that a non-blocking operation must be retried\n# at a later time.  On most platforms they're the same value, but on\n# some they differ.\n_ERRNO_WOULDBLOCK = (errno.EWOULDBLOCK, errno.EAGAIN)\n\n# These errnos indicate that a connection has been abruptly terminated.\n# They should be caught and handled less noisily than other errors.\n_ERRNO_CONNRESET = (errno.ECONNRESET, errno.ECONNABORTED, errno.EPIPE)\n\n\nclass StreamClosedError(IOError):\n    \"\"\"Exception raised by `IOStream` methods when the stream is closed.\n\n    Note that the close callback is scheduled to run *after* other\n    callbacks on the stream (to allow for buffered data to be processed),\n    so you may see this error before you see the close callback.\n    \"\"\"\n    pass\n\n\nclass BaseIOStream(object):\n    \"\"\"A utility class to write to and read from a non-blocking file or socket.\n\n    We support a non-blocking ``write()`` and a family of ``read_*()`` methods.\n    All of the methods take callbacks (since writing and reading are\n    non-blocking and asynchronous).\n\n    When a stream is closed due to an error, the IOStream's ``error``\n    attribute contains the exception object.\n\n    Subclasses must implement `fileno`, `close_fd`, `write_to_fd`,\n    `read_from_fd`, and optionally `get_fd_error`.\n    \"\"\"\n    def __init__(self, io_loop=None, max_buffer_size=None,\n                 read_chunk_size=4096):\n        self.io_loop = io_loop or ioloop.IOLoop.current()\n        self.max_buffer_size = max_buffer_size or 104857600\n        self.read_chunk_size = read_chunk_size\n        self.error = None\n        self._read_buffer = collections.deque()\n        self._write_buffer = collections.deque()\n        self._read_buffer_size = 0\n        self._write_buffer_frozen = False\n        self._read_delimiter = None\n        self._read_regex = None\n        self._read_bytes = None\n        self._read_until_close = False\n        self._read_callback = None\n        self._read_future = None\n        self._streaming_callback = None\n        self._write_callback = None\n        self._write_future = None\n        self._close_callback = None\n        self._connect_callback = None\n        self._connect_future = None\n        self._connecting = False\n        self._state = None\n        self._pending_callbacks = 0\n        self._closed = False\n\n    def fileno(self):\n        \"\"\"Returns the file descriptor for this stream.\"\"\"\n        raise NotImplementedError()\n\n    def close_fd(self):\n        \"\"\"Closes the file underlying this stream.\n\n        ``close_fd`` is called by `BaseIOStream` and should not be called\n        elsewhere; other users should call `close` instead.\n        \"\"\"\n        raise NotImplementedError()\n\n    def write_to_fd(self, data):\n        \"\"\"Attempts to write ``data`` to the underlying file.\n\n        Returns the number of bytes written.\n        \"\"\"\n        raise NotImplementedError()\n\n    def read_from_fd(self):\n        \"\"\"Attempts to read from the underlying file.\n\n        Returns ``None`` if there was nothing to read (the socket\n        returned `~errno.EWOULDBLOCK` or equivalent), otherwise\n        returns the data.  When possible, should return no more than\n        ``self.read_chunk_size`` bytes at a time.\n        \"\"\"\n        raise NotImplementedError()\n\n    def get_fd_error(self):\n        \"\"\"Returns information about any error on the underlying file.\n\n        This method is called after the `.IOLoop` has signaled an error on the\n        file descriptor, and should return an Exception (such as `socket.error`\n        with additional information, or None if no such information is\n        available.\n        \"\"\"\n        return None\n\n    def read_until_regex(self, regex, callback=None):\n        \"\"\"Run ``callback`` when we read the given regex pattern.\n\n        The callback will get the data read (including the data that\n        matched the regex and anything that came before it) as an argument.\n        \"\"\"\n        future = self._set_read_callback(callback)\n        self._read_regex = re.compile(regex)\n        self._try_inline_read()\n        return future\n\n    def read_until(self, delimiter, callback=None):\n        \"\"\"Run ``callback`` when we read the given delimiter.\n\n        The callback will get the data read (including the delimiter)\n        as an argument.\n        \"\"\"\n        future = self._set_read_callback(callback)\n        self._read_delimiter = delimiter\n        self._try_inline_read()\n        return future\n\n    def read_bytes(self, num_bytes, callback=None, streaming_callback=None):\n        \"\"\"Run callback when we read the given number of bytes.\n\n        If a ``streaming_callback`` is given, it will be called with chunks\n        of data as they become available, and the argument to the final\n        ``callback`` will be empty.  Otherwise, the ``callback`` gets\n        the data as an argument.\n        \"\"\"\n        future = self._set_read_callback(callback)\n        assert isinstance(num_bytes, numbers.Integral)\n        self._read_bytes = num_bytes\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        self._try_inline_read()\n        return future\n\n    def read_until_close(self, callback=None, streaming_callback=None):\n        \"\"\"Reads all data from the socket until it is closed.\n\n        If a ``streaming_callback`` is given, it will be called with chunks\n        of data as they become available, and the argument to the final\n        ``callback`` will be empty.  Otherwise, the ``callback`` gets the\n        data as an argument.\n\n        Subject to ``max_buffer_size`` limit from `IOStream` constructor if\n        a ``streaming_callback`` is not used.\n        \"\"\"\n        future = self._set_read_callback(callback)\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        if self.closed():\n            if self._streaming_callback is not None:\n                self._run_callback(self._streaming_callback,\n                                   self._consume(self._read_buffer_size))\n            self._run_read_callback(self._consume(self._read_buffer_size))\n            return future\n        self._read_until_close = True\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        self._try_inline_read()\n        return future\n\n    def write(self, data, callback=None):\n        \"\"\"Write the given data to this stream.\n\n        If ``callback`` is given, we call it when all of the buffered write\n        data has been successfully written to the stream. If there was\n        previously buffered write data and an old write callback, that\n        callback is simply overwritten with this new callback.\n        \"\"\"\n        assert isinstance(data, bytes_type)\n        self._check_closed()\n        # We use bool(_write_buffer) as a proxy for write_buffer_size>0,\n        # so never put empty strings in the buffer.\n        if data:\n            # Break up large contiguous strings before inserting them in the\n            # write buffer, so we don't have to recopy the entire thing\n            # as we slice off pieces to send to the socket.\n            WRITE_BUFFER_CHUNK_SIZE = 128 * 1024\n            for i in range(0, len(data), WRITE_BUFFER_CHUNK_SIZE):\n                self._write_buffer.append(data[i:i + WRITE_BUFFER_CHUNK_SIZE])\n        if callback is not None:\n            self._write_callback = stack_context.wrap(callback)\n            future = None\n        else:\n            future = self._write_future = TracebackFuture()\n        if not self._connecting:\n            self._handle_write()\n            if self._write_buffer:\n                self._add_io_state(self.io_loop.WRITE)\n            self._maybe_add_error_listener()\n        return future\n\n    def set_close_callback(self, callback):\n        \"\"\"Call the given callback when the stream is closed.\"\"\"\n        self._close_callback = stack_context.wrap(callback)\n\n    def close(self, exc_info=False):\n        \"\"\"Close this stream.\n\n        If ``exc_info`` is true, set the ``error`` attribute to the current\n        exception from `sys.exc_info` (or if ``exc_info`` is a tuple,\n        use that instead of `sys.exc_info`).\n        \"\"\"\n        if not self.closed():\n            if exc_info:\n                if not isinstance(exc_info, tuple):\n                    exc_info = sys.exc_info()\n                if any(exc_info):\n                    self.error = exc_info[1]\n            if self._read_until_close:\n                if (self._streaming_callback is not None and\n                        self._read_buffer_size):\n                    self._run_callback(self._streaming_callback,\n                                       self._consume(self._read_buffer_size))\n                self._read_until_close = False\n                self._run_read_callback(self._consume(self._read_buffer_size))\n            if self._state is not None:\n                self.io_loop.remove_handler(self.fileno())\n                self._state = None\n            self.close_fd()\n            self._closed = True\n        self._maybe_run_close_callback()\n\n    def _maybe_run_close_callback(self):\n        # If there are pending callbacks, don't run the close callback\n        # until they're done (see _maybe_add_error_handler)\n        if self.closed() and self._pending_callbacks == 0:\n            futures = []\n            if self._read_future is not None:\n                futures.append(self._read_future)\n                self._read_future = None\n            if self._write_future is not None:\n                futures.append(self._write_future)\n                self._write_future = None\n            if self._connect_future is not None:\n                futures.append(self._connect_future)\n                self._connect_future = None\n            for future in futures:\n                future.set_exception(StreamClosedError())\n            if self._close_callback is not None:\n                cb = self._close_callback\n                self._close_callback = None\n                self._run_callback(cb)\n            # Delete any unfinished callbacks to break up reference cycles.\n            self._read_callback = self._write_callback = None\n            # Clear the buffers so they can be cleared immediately even\n            # if the IOStream object is kept alive by a reference cycle.\n            # TODO: Clear the read buffer too; it currently breaks some tests.\n            self._write_buffer = None\n\n    def reading(self):\n        \"\"\"Returns true if we are currently reading from the stream.\"\"\"\n        return self._read_callback is not None\n\n    def writing(self):\n        \"\"\"Returns true if we are currently writing to the stream.\"\"\"\n        return bool(self._write_buffer)\n\n    def closed(self):\n        \"\"\"Returns true if the stream has been closed.\"\"\"\n        return self._closed\n\n    def set_nodelay(self, value):\n        \"\"\"Sets the no-delay flag for this stream.\n\n        By default, data written to TCP streams may be held for a time\n        to make the most efficient use of bandwidth (according to\n        Nagle's algorithm).  The no-delay flag requests that data be\n        written as soon as possible, even if doing so would consume\n        additional bandwidth.\n\n        This flag is currently defined only for TCP-based ``IOStreams``.\n\n        .. versionadded:: 3.1\n        \"\"\"\n        pass\n\n    def _handle_events(self, fd, events):\n        if self.closed():\n            gen_log.warning(\"Got events for closed stream %s\", fd)\n            return\n        try:\n            if events & self.io_loop.READ:\n                self._handle_read()\n            if self.closed():\n                return\n            if events & self.io_loop.WRITE:\n                if self._connecting:\n                    self._handle_connect()\n                self._handle_write()\n            if self.closed():\n                return\n            if events & self.io_loop.ERROR:\n                self.error = self.get_fd_error()\n                # We may have queued up a user callback in _handle_read or\n                # _handle_write, so don't close the IOStream until those\n                # callbacks have had a chance to run.\n                self.io_loop.add_callback(self.close)\n                return\n            state = self.io_loop.ERROR\n            if self.reading():\n                state |= self.io_loop.READ\n            if self.writing():\n                state |= self.io_loop.WRITE\n            if state == self.io_loop.ERROR:\n                state |= self.io_loop.READ\n            if state != self._state:\n                assert self._state is not None, \\\n                    \"shouldn't happen: _handle_events without self._state\"\n                self._state = state\n                self.io_loop.update_handler(self.fileno(), self._state)\n        except Exception:\n            gen_log.error(\"Uncaught exception, closing connection.\",\n                          exc_info=True)\n            self.close(exc_info=True)\n            raise\n\n    def _run_callback(self, callback, *args):\n        def wrapper():\n            self._pending_callbacks -= 1\n            try:\n                callback(*args)\n            except Exception:\n                app_log.error(\"Uncaught exception, closing connection.\",\n                              exc_info=True)\n                # Close the socket on an uncaught exception from a user callback\n                # (It would eventually get closed when the socket object is\n                # gc'd, but we don't want to rely on gc happening before we\n                # run out of file descriptors)\n                self.close(exc_info=True)\n                # Re-raise the exception so that IOLoop.handle_callback_exception\n                # can see it and log the error\n                raise\n            self._maybe_add_error_listener()\n        # We schedule callbacks to be run on the next IOLoop iteration\n        # rather than running them directly for several reasons:\n        # * Prevents unbounded stack growth when a callback calls an\n        #   IOLoop operation that immediately runs another callback\n        # * Provides a predictable execution context for e.g.\n        #   non-reentrant mutexes\n        # * Ensures that the try/except in wrapper() is run outside\n        #   of the application's StackContexts\n        with stack_context.NullContext():\n            # stack_context was already captured in callback, we don't need to\n            # capture it again for IOStream's wrapper.  This is especially\n            # important if the callback was pre-wrapped before entry to\n            # IOStream (as in HTTPConnection._header_callback), as we could\n            # capture and leak the wrong context here.\n            self._pending_callbacks += 1\n            self.io_loop.add_callback(wrapper)\n\n    def _handle_read(self):\n        try:\n            try:\n                # Pretend to have a pending callback so that an EOF in\n                # _read_to_buffer doesn't trigger an immediate close\n                # callback.  At the end of this method we'll either\n                # estabilsh a real pending callback via\n                # _read_from_buffer or run the close callback.\n                #\n                # We need two try statements here so that\n                # pending_callbacks is decremented before the `except`\n                # clause below (which calls `close` and does need to\n                # trigger the callback)\n                self._pending_callbacks += 1\n                while not self.closed():\n                    # Read from the socket until we get EWOULDBLOCK or equivalent.\n                    # SSL sockets do some internal buffering, and if the data is\n                    # sitting in the SSL object's buffer select() and friends\n                    # can't see it; the only way to find out if it's there is to\n                    # try to read it.\n                    if self._read_to_buffer() == 0:\n                        break\n            finally:\n                self._pending_callbacks -= 1\n        except Exception:\n            gen_log.warning(\"error on read\", exc_info=True)\n            self.close(exc_info=True)\n            return\n        if self._read_from_buffer():\n            return\n        else:\n            self._maybe_run_close_callback()\n\n    def _set_read_callback(self, callback):\n        assert self._read_callback is None, \"Already reading\"\n        assert self._read_future is None, \"Already reading\"\n        if callback is not None:\n            self._read_callback = stack_context.wrap(callback)\n        else:\n            self._read_future = TracebackFuture()\n        return self._read_future\n\n    def _run_read_callback(self, data):\n        self._streaming_callback = None\n        if self._read_future is not None:\n            future = self._read_future\n            self._read_future = None\n            future.set_result(data)\n        if self._read_callback is not None:\n            callback = self._read_callback\n            self._read_callback = None\n            self._run_callback(callback, data)\n        else:\n            # If we scheduled a callback, we will add the error listener\n            # afterwards.  If we didn't, we have to do it now.\n            self._maybe_add_error_listener()\n\n    def _try_inline_read(self):\n        \"\"\"Attempt to complete the current read operation from buffered data.\n\n        If the read can be completed without blocking, schedules the\n        read callback on the next IOLoop iteration; otherwise starts\n        listening for reads on the socket.\n        \"\"\"\n        # See if we've already got the data from a previous read\n        if self._read_from_buffer():\n            return\n        self._check_closed()\n        try:\n            try:\n                # See comments in _handle_read about incrementing _pending_callbacks\n                self._pending_callbacks += 1\n                while not self.closed():\n                    if self._read_to_buffer() == 0:\n                        break\n            finally:\n                self._pending_callbacks -= 1\n        except Exception:\n            # If there was an in _read_to_buffer, we called close() already,\n            # but couldn't run the close callback because of _pending_callbacks.\n            # Before we escape from this function, run the close callback if\n            # applicable.\n            self._maybe_run_close_callback()\n            raise\n        if self._read_from_buffer():\n            return\n        self._maybe_add_error_listener()\n\n    def _read_to_buffer(self):\n        \"\"\"Reads from the socket and appends the result to the read buffer.\n\n        Returns the number of bytes read.  Returns 0 if there is nothing\n        to read (i.e. the read returns EWOULDBLOCK or equivalent).  On\n        error closes the socket and raises an exception.\n        \"\"\"\n        try:\n            chunk = self.read_from_fd()\n        except (socket.error, IOError, OSError) as e:\n            # ssl.SSLError is a subclass of socket.error\n            if e.args[0] in _ERRNO_CONNRESET:\n                # Treat ECONNRESET as a connection close rather than\n                # an error to minimize log spam  (the exception will\n                # be available on self.error for apps that care).\n                self.close(exc_info=True)\n                return\n            self.close(exc_info=True)\n            raise\n        if chunk is None:\n            return 0\n        self._read_buffer.append(chunk)\n        self._read_buffer_size += len(chunk)\n        if self._read_buffer_size >= self.max_buffer_size:\n            gen_log.error(\"Reached maximum read buffer size\")\n            self.close()\n            raise IOError(\"Reached maximum read buffer size\")\n        return len(chunk)\n\n    def _read_from_buffer(self):\n        \"\"\"Attempts to complete the currently-pending read from the buffer.\n\n        Returns True if the read was completed.\n        \"\"\"\n        if self._streaming_callback is not None and self._read_buffer_size:\n            bytes_to_consume = self._read_buffer_size\n            if self._read_bytes is not None:\n                bytes_to_consume = min(self._read_bytes, bytes_to_consume)\n                self._read_bytes -= bytes_to_consume\n            self._run_callback(self._streaming_callback,\n                               self._consume(bytes_to_consume))\n        if self._read_bytes is not None and self._read_buffer_size >= self._read_bytes:\n            num_bytes = self._read_bytes\n            self._read_bytes = None\n            self._run_read_callback(self._consume(num_bytes))\n            return True\n        elif self._read_delimiter is not None:\n            # Multi-byte delimiters (e.g. '\\r\\n') may straddle two\n            # chunks in the read buffer, so we can't easily find them\n            # without collapsing the buffer.  However, since protocols\n            # using delimited reads (as opposed to reads of a known\n            # length) tend to be \"line\" oriented, the delimiter is likely\n            # to be in the first few chunks.  Merge the buffer gradually\n            # since large merges are relatively expensive and get undone in\n            # consume().\n            if self._read_buffer:\n                while True:\n                    loc = self._read_buffer[0].find(self._read_delimiter)\n                    if loc != -1:\n                        delimiter_len = len(self._read_delimiter)\n                        self._read_delimiter = None\n                        self._run_read_callback(\n                            self._consume(loc + delimiter_len))\n                        return True\n                    if len(self._read_buffer) == 1:\n                        break\n                    _double_prefix(self._read_buffer)\n        elif self._read_regex is not None:\n            if self._read_buffer:\n                while True:\n                    m = self._read_regex.search(self._read_buffer[0])\n                    if m is not None:\n                        self._read_regex = None\n                        self._run_read_callback(self._consume(m.end()))\n                        return True\n                    if len(self._read_buffer) == 1:\n                        break\n                    _double_prefix(self._read_buffer)\n        return False\n\n    def _handle_write(self):\n        while self._write_buffer:\n            try:\n                if not self._write_buffer_frozen:\n                    # On windows, socket.send blows up if given a\n                    # write buffer that's too large, instead of just\n                    # returning the number of bytes it was able to\n                    # process.  Therefore we must not call socket.send\n                    # with more than 128KB at a time.\n                    _merge_prefix(self._write_buffer, 128 * 1024)\n                num_bytes = self.write_to_fd(self._write_buffer[0])\n                if num_bytes == 0:\n                    # With OpenSSL, if we couldn't write the entire buffer,\n                    # the very same string object must be used on the\n                    # next call to send.  Therefore we suppress\n                    # merging the write buffer after an incomplete send.\n                    # A cleaner solution would be to set\n                    # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, but this is\n                    # not yet accessible from python\n                    # (http://bugs.python.org/issue8240)\n                    self._write_buffer_frozen = True\n                    break\n                self._write_buffer_frozen = False\n                _merge_prefix(self._write_buffer, num_bytes)\n                self._write_buffer.popleft()\n            except (socket.error, IOError, OSError) as e:\n                if e.args[0] in _ERRNO_WOULDBLOCK:\n                    self._write_buffer_frozen = True\n                    break\n                else:\n                    if e.args[0] not in _ERRNO_CONNRESET:\n                        # Broken pipe errors are usually caused by connection\n                        # reset, and its better to not log EPIPE errors to\n                        # minimize log spam\n                        gen_log.warning(\"Write error on %s: %s\",\n                                        self.fileno(), e)\n                    self.close(exc_info=True)\n                    return\n        if not self._write_buffer:\n            if self._write_callback:\n                callback = self._write_callback\n                self._write_callback = None\n                self._run_callback(callback)\n            if self._write_future:\n                future = self._write_future\n                self._write_future = None\n                future.set_result(None)\n\n    def _consume(self, loc):\n        if loc == 0:\n            return b\"\"\n        _merge_prefix(self._read_buffer, loc)\n        self._read_buffer_size -= loc\n        return self._read_buffer.popleft()\n\n    def _check_closed(self):\n        if self.closed():\n            raise StreamClosedError(\"Stream is closed\")\n\n    def _maybe_add_error_listener(self):\n        if self._state is None and self._pending_callbacks == 0:\n            if self.closed():\n                self._maybe_run_close_callback()\n            else:\n                self._add_io_state(ioloop.IOLoop.READ)\n\n    def _add_io_state(self, state):\n        \"\"\"Adds `state` (IOLoop.{READ,WRITE} flags) to our event handler.\n\n        Implementation notes: Reads and writes have a fast path and a\n        slow path.  The fast path reads synchronously from socket\n        buffers, while the slow path uses `_add_io_state` to schedule\n        an IOLoop callback.  Note that in both cases, the callback is\n        run asynchronously with `_run_callback`.\n\n        To detect closed connections, we must have called\n        `_add_io_state` at some point, but we want to delay this as\n        much as possible so we don't have to set an `IOLoop.ERROR`\n        listener that will be overwritten by the next slow-path\n        operation.  As long as there are callbacks scheduled for\n        fast-path ops, those callbacks may do more reads.\n        If a sequence of fast-path ops do not end in a slow-path op,\n        (e.g. for an @asynchronous long-poll request), we must add\n        the error handler.  This is done in `_run_callback` and `write`\n        (since the write callback is optional so we can have a\n        fast-path write with no `_run_callback`)\n        \"\"\"\n        if self.closed():\n            # connection has been closed, so there can be no future events\n            return\n        if self._state is None:\n            self._state = ioloop.IOLoop.ERROR | state\n            with stack_context.NullContext():\n                self.io_loop.add_handler(\n                    self.fileno(), self._handle_events, self._state)\n        elif not self._state & state:\n            self._state = self._state | state\n            self.io_loop.update_handler(self.fileno(), self._state)\n\n\nclass IOStream(BaseIOStream):\n    r\"\"\"Socket-based `IOStream` implementation.\n\n    This class supports the read and write methods from `BaseIOStream`\n    plus a `connect` method.\n\n    The ``socket`` parameter may either be connected or unconnected.\n    For server operations the socket is the result of calling\n    `socket.accept <socket.socket.accept>`.  For client operations the\n    socket is created with `socket.socket`, and may either be\n    connected before passing it to the `IOStream` or connected with\n    `IOStream.connect`.\n\n    A very simple (and broken) HTTP client using this class::\n\n        import tornado.ioloop\n        import tornado.iostream\n        import socket\n\n        def send_request():\n            stream.write(b\"GET / HTTP/1.0\\r\\nHost: friendfeed.com\\r\\n\\r\\n\")\n            stream.read_until(b\"\\r\\n\\r\\n\", on_headers)\n\n        def on_headers(data):\n            headers = {}\n            for line in data.split(b\"\\r\\n\"):\n               parts = line.split(b\":\")\n               if len(parts) == 2:\n                   headers[parts[0].strip()] = parts[1].strip()\n            stream.read_bytes(int(headers[b\"Content-Length\"]), on_body)\n\n        def on_body(data):\n            print data\n            stream.close()\n            tornado.ioloop.IOLoop.instance().stop()\n\n        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)\n        stream = tornado.iostream.IOStream(s)\n        stream.connect((\"friendfeed.com\", 80), send_request)\n        tornado.ioloop.IOLoop.instance().start()\n    \"\"\"\n    def __init__(self, socket, *args, **kwargs):\n        self.socket = socket\n        self.socket.setblocking(False)\n        super(IOStream, self).__init__(*args, **kwargs)\n\n    def fileno(self):\n        return self.socket\n\n    def close_fd(self):\n        self.socket.close()\n        self.socket = None\n\n    def get_fd_error(self):\n        errno = self.socket.getsockopt(socket.SOL_SOCKET,\n                                       socket.SO_ERROR)\n        return socket.error(errno, os.strerror(errno))\n\n    def read_from_fd(self):\n        try:\n            chunk = self.socket.recv(self.read_chunk_size)\n        except socket.error as e:\n            if e.args[0] in _ERRNO_WOULDBLOCK:\n                return None\n            else:\n                raise\n        if not chunk:\n            self.close()\n            return None\n        return chunk\n\n    def write_to_fd(self, data):\n        return self.socket.send(data)\n\n    def connect(self, address, callback=None, server_hostname=None):\n        \"\"\"Connects the socket to a remote address without blocking.\n\n        May only be called if the socket passed to the constructor was\n        not previously connected.  The address parameter is in the\n        same format as for `socket.connect <socket.socket.connect>`,\n        i.e. a ``(host, port)`` tuple.  If ``callback`` is specified,\n        it will be called when the connection is completed.\n\n        If specified, the ``server_hostname`` parameter will be used\n        in SSL connections for certificate validation (if requested in\n        the ``ssl_options``) and SNI (if supported; requires\n        Python 3.2+).\n\n        Note that it is safe to call `IOStream.write\n        <BaseIOStream.write>` while the connection is pending, in\n        which case the data will be written as soon as the connection\n        is ready.  Calling `IOStream` read methods before the socket is\n        connected works on some platforms but is non-portable.\n        \"\"\"\n        self._connecting = True\n        try:\n            self.socket.connect(address)\n        except socket.error as e:\n            # In non-blocking mode we expect connect() to raise an\n            # exception with EINPROGRESS or EWOULDBLOCK.\n            #\n            # On freebsd, other errors such as ECONNREFUSED may be\n            # returned immediately when attempting to connect to\n            # localhost, so handle them the same way as an error\n            # reported later in _handle_connect.\n            if (e.args[0] != errno.EINPROGRESS and\n                    e.args[0] not in _ERRNO_WOULDBLOCK):\n                gen_log.warning(\"Connect error on fd %s: %s\",\n                                self.socket.fileno(), e)\n                self.close(exc_info=True)\n                return\n        if callback is not None:\n            self._connect_callback = stack_context.wrap(callback)\n            future = None\n        else:\n            future = self._connect_future = TracebackFuture()\n        self._add_io_state(self.io_loop.WRITE)\n        return future\n\n    def _handle_connect(self):\n        err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)\n        if err != 0:\n            self.error = socket.error(err, os.strerror(err))\n            # IOLoop implementations may vary: some of them return\n            # an error state before the socket becomes writable, so\n            # in that case a connection failure would be handled by the\n            # error path in _handle_events instead of here.\n            gen_log.warning(\"Connect error on fd %s: %s\",\n                            self.socket.fileno(), errno.errorcode[err])\n            self.close()\n            return\n        if self._connect_callback is not None:\n            callback = self._connect_callback\n            self._connect_callback = None\n            self._run_callback(callback)\n        if self._connect_future is not None:\n            future = self._connect_future\n            self._connect_future = None\n            future.set_result(None)\n        self._connecting = False\n\n    def set_nodelay(self, value):\n        if (self.socket is not None and\n                self.socket.family in (socket.AF_INET, socket.AF_INET6)):\n            try:\n                self.socket.setsockopt(socket.IPPROTO_TCP,\n                                       socket.TCP_NODELAY, 1 if value else 0)\n            except socket.error as e:\n                # Sometimes setsockopt will fail if the socket is closed\n                # at the wrong time.  This can happen with HTTPServer\n                # resetting the value to false between requests.\n                if e.errno not in (errno.EINVAL, errno.ECONNRESET):\n                    raise\n\n\nclass SSLIOStream(IOStream):\n    \"\"\"A utility class to write to and read from a non-blocking SSL socket.\n\n    If the socket passed to the constructor is already connected,\n    it should be wrapped with::\n\n        ssl.wrap_socket(sock, do_handshake_on_connect=False, **kwargs)\n\n    before constructing the `SSLIOStream`.  Unconnected sockets will be\n    wrapped when `IOStream.connect` is finished.\n    \"\"\"\n    def __init__(self, *args, **kwargs):\n        \"\"\"The ``ssl_options`` keyword argument may either be a dictionary\n        of keywords arguments for `ssl.wrap_socket`, or an `ssl.SSLContext`\n        object.\n        \"\"\"\n        self._ssl_options = kwargs.pop('ssl_options', {})\n        super(SSLIOStream, self).__init__(*args, **kwargs)\n        self._ssl_accepting = True\n        self._handshake_reading = False\n        self._handshake_writing = False\n        self._ssl_connect_callback = None\n        self._server_hostname = None\n\n        # If the socket is already connected, attempt to start the handshake.\n        try:\n            self.socket.getpeername()\n        except socket.error:\n            pass\n        else:\n            # Indirectly start the handshake, which will run on the next\n            # IOLoop iteration and then the real IO state will be set in\n            # _handle_events.\n            self._add_io_state(self.io_loop.WRITE)\n\n    def reading(self):\n        return self._handshake_reading or super(SSLIOStream, self).reading()\n\n    def writing(self):\n        return self._handshake_writing or super(SSLIOStream, self).writing()\n\n    def _do_ssl_handshake(self):\n        # Based on code from test_ssl.py in the python stdlib\n        try:\n            self._handshake_reading = False\n            self._handshake_writing = False\n            self.socket.do_handshake()\n        except ssl.SSLError as err:\n            if err.args[0] == ssl.SSL_ERROR_WANT_READ:\n                self._handshake_reading = True\n                return\n            elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:\n                self._handshake_writing = True\n                return\n            elif err.args[0] in (ssl.SSL_ERROR_EOF,\n                                 ssl.SSL_ERROR_ZERO_RETURN):\n                return self.close(exc_info=True)\n            elif err.args[0] == ssl.SSL_ERROR_SSL:\n                try:\n                    peer = self.socket.getpeername()\n                except Exception:\n                    peer = '(not connected)'\n                gen_log.warning(\"SSL Error on %s %s: %s\",\n                                self.socket.fileno(), peer, err)\n                return self.close(exc_info=True)\n            raise\n        except socket.error as err:\n            if err.args[0] in _ERRNO_CONNRESET:\n                return self.close(exc_info=True)\n        except AttributeError:\n            # On Linux, if the connection was reset before the call to\n            # wrap_socket, do_handshake will fail with an\n            # AttributeError.\n            return self.close(exc_info=True)\n        else:\n            self._ssl_accepting = False\n            if not self._verify_cert(self.socket.getpeercert()):\n                self.close()\n                return\n            if self._ssl_connect_callback is not None:\n                callback = self._ssl_connect_callback\n                self._ssl_connect_callback = None\n                self._run_callback(callback)\n\n    def _verify_cert(self, peercert):\n        \"\"\"Returns True if peercert is valid according to the configured\n        validation mode and hostname.\n\n        The ssl handshake already tested the certificate for a valid\n        CA signature; the only thing that remains is to check\n        the hostname.\n        \"\"\"\n        if isinstance(self._ssl_options, dict):\n            verify_mode = self._ssl_options.get('cert_reqs', ssl.CERT_NONE)\n        elif isinstance(self._ssl_options, ssl.SSLContext):\n            verify_mode = self._ssl_options.verify_mode\n        assert verify_mode in (ssl.CERT_NONE, ssl.CERT_REQUIRED, ssl.CERT_OPTIONAL)\n        if verify_mode == ssl.CERT_NONE or self._server_hostname is None:\n            return True\n        cert = self.socket.getpeercert()\n        if cert is None and verify_mode == ssl.CERT_REQUIRED:\n            gen_log.warning(\"No SSL certificate given\")\n            return False\n        try:\n            ssl_match_hostname(peercert, self._server_hostname)\n        except SSLCertificateError:\n            gen_log.warning(\"Invalid SSL certificate\", exc_info=True)\n            return False\n        else:\n            return True\n\n    def _handle_read(self):\n        if self._ssl_accepting:\n            self._do_ssl_handshake()\n            return\n        super(SSLIOStream, self)._handle_read()\n\n    def _handle_write(self):\n        if self._ssl_accepting:\n            self._do_ssl_handshake()\n            return\n        super(SSLIOStream, self)._handle_write()\n\n    def connect(self, address, callback=None, server_hostname=None):\n        # Save the user's callback and run it after the ssl handshake\n        # has completed.\n        self._ssl_connect_callback = stack_context.wrap(callback)\n        self._server_hostname = server_hostname\n        # Note: Since we don't pass our callback argument along to\n        # super.connect(), this will always return a Future.\n        # This is harmless, but a bit less efficient than it could be.\n        return super(SSLIOStream, self).connect(address, callback=None)\n\n    def _handle_connect(self):\n        # When the connection is complete, wrap the socket for SSL\n        # traffic.  Note that we do this by overriding _handle_connect\n        # instead of by passing a callback to super().connect because\n        # user callbacks are enqueued asynchronously on the IOLoop,\n        # but since _handle_events calls _handle_connect immediately\n        # followed by _handle_write we need this to be synchronous.\n        #\n        # The IOLoop will get confused if we swap out self.socket while the\n        # fd is registered, so remove it now and re-register after\n        # wrap_socket().\n        self.io_loop.remove_handler(self.socket)\n        old_state = self._state\n        self._state = None\n        self.socket = ssl_wrap_socket(self.socket, self._ssl_options,\n                                      server_hostname=self._server_hostname,\n                                      do_handshake_on_connect=False)\n        self._add_io_state(old_state)\n        super(SSLIOStream, self)._handle_connect()\n\n    def read_from_fd(self):\n        if self._ssl_accepting:\n            # If the handshake hasn't finished yet, there can't be anything\n            # to read (attempting to read may or may not raise an exception\n            # depending on the SSL version)\n            return None\n        try:\n            # SSLSocket objects have both a read() and recv() method,\n            # while regular sockets only have recv().\n            # The recv() method blocks (at least in python 2.6) if it is\n            # called when there is nothing to read, so we have to use\n            # read() instead.\n            chunk = self.socket.read(self.read_chunk_size)\n        except ssl.SSLError as e:\n            # SSLError is a subclass of socket.error, so this except\n            # block must come first.\n            if e.args[0] == ssl.SSL_ERROR_WANT_READ:\n                return None\n            else:\n                raise\n        except socket.error as e:\n            if e.args[0] in _ERRNO_WOULDBLOCK:\n                return None\n            else:\n                raise\n        if not chunk:\n            self.close()\n            return None\n        return chunk\n\n\nclass PipeIOStream(BaseIOStream):\n    \"\"\"Pipe-based `IOStream` implementation.\n\n    The constructor takes an integer file descriptor (such as one returned\n    by `os.pipe`) rather than an open file object.  Pipes are generally\n    one-way, so a `PipeIOStream` can be used for reading or writing but not\n    both.\n    \"\"\"\n    def __init__(self, fd, *args, **kwargs):\n        self.fd = fd\n        _set_nonblocking(fd)\n        super(PipeIOStream, self).__init__(*args, **kwargs)\n\n    def fileno(self):\n        return self.fd\n\n    def close_fd(self):\n        os.close(self.fd)\n\n    def write_to_fd(self, data):\n        return os.write(self.fd, data)\n\n    def read_from_fd(self):\n        try:\n            chunk = os.read(self.fd, self.read_chunk_size)\n        except (IOError, OSError) as e:\n            if e.args[0] in _ERRNO_WOULDBLOCK:\n                return None\n            elif e.args[0] == errno.EBADF:\n                # If the writing half of a pipe is closed, select will\n                # report it as readable but reads will fail with EBADF.\n                self.close(exc_info=True)\n                return None\n            else:\n                raise\n        if not chunk:\n            self.close()\n            return None\n        return chunk\n\n\ndef _double_prefix(deque):\n    \"\"\"Grow by doubling, but don't split the second chunk just because the\n    first one is small.\n    \"\"\"\n    new_len = max(len(deque[0]) * 2,\n                  (len(deque[0]) + len(deque[1])))\n    _merge_prefix(deque, new_len)\n\n\ndef _merge_prefix(deque, size):\n    \"\"\"Replace the first entries in a deque of strings with a single\n    string of up to size bytes.\n\n    >>> d = collections.deque(['abc', 'de', 'fghi', 'j'])\n    >>> _merge_prefix(d, 5); print(d)\n    deque(['abcde', 'fghi', 'j'])\n\n    Strings will be split as necessary to reach the desired size.\n    >>> _merge_prefix(d, 7); print(d)\n    deque(['abcdefg', 'hi', 'j'])\n\n    >>> _merge_prefix(d, 3); print(d)\n    deque(['abc', 'defg', 'hi', 'j'])\n\n    >>> _merge_prefix(d, 100); print(d)\n    deque(['abcdefghij'])\n    \"\"\"\n    if len(deque) == 1 and len(deque[0]) <= size:\n        return\n    prefix = []\n    remaining = size\n    while deque and remaining > 0:\n        chunk = deque.popleft()\n        if len(chunk) > remaining:\n            deque.appendleft(chunk[remaining:])\n            chunk = chunk[:remaining]\n        prefix.append(chunk)\n        remaining -= len(chunk)\n    # This data structure normally just contains byte strings, but\n    # the unittest gets messy if it doesn't use the default str() type,\n    # so do the merge based on the type of data that's actually present.\n    if prefix:\n        deque.appendleft(type(prefix[0])().join(prefix))\n    if not deque:\n        deque.appendleft(b\"\")\n\n\ndef doctests():\n    import doctest\n    return doctest.DocTestSuite()\n",
            "header": {
                "file": {
                    "path": "tornado/iostream.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "faf657a4",
                "new_commit_hash": "113ee094",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/tornado/iostream.py"
            },
            "plus_file": {
                "path": "b/tornado/iostream.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 449,
                            "length": 6
                        },
                        "new_range": {
                            "start": 449,
                            "length": 10
                        },
                        "section": "class BaseIOStream(object):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "            callback = self._read_callback",
                                "type": "context"
                            },
                            {
                                "content": "            self._read_callback = None",
                                "type": "context"
                            },
                            {
                                "content": "            self._run_callback(callback, data)",
                                "type": "context"
                            },
                            {
                                "content": "        else:",
                                "type": "added"
                            },
                            {
                                "content": "            # If we scheduled a callback, we will add the error listener",
                                "type": "added"
                            },
                            {
                                "content": "            # afterwards.  If we didn't, we have to do it now.",
                                "type": "added"
                            },
                            {
                                "content": "            self._maybe_add_error_listener()",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def _try_inline_read(self):",
                                "type": "context"
                            },
                            {
                                "content": "        \"\"\"Attempt to complete the current read operation from buffered data.",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/iostream.py",
                            "type": "method",
                            "name": "BaseIOStream._run_read_callback",
                            "content": "class BaseIOStream(object):\n    \"\"\"A utility class to write to and read from a non-blocking file or socket.\n\n    We support a non-blocking ``write()`` and a family of ``read_*()`` methods.\n    All of the methods take callbacks (since writing and reading are\n    non-blocking and asynchronous).\n\n    When a stream is closed due to an error, the IOStream's ``error``\n    attribute contains the exception object.\n\n    Subclasses must implement `fileno`, `close_fd`, `write_to_fd`,\n    `read_from_fd`, and optionally `get_fd_error`.\n    \"\"\"\n    def __init__(self, io_loop=None, max_buffer_size=None,\n                 read_chunk_size=4096):\n        self.io_loop = io_loop or ioloop.IOLoop.current()\n        self.max_buffer_size = max_buffer_size or 104857600\n        self.read_chunk_size = read_chunk_size\n        self.error = None\n        self._read_buffer = collections.deque()\n        self._write_buffer = collections.deque()\n        self._read_buffer_size = 0\n        self._write_buffer_frozen = False\n        self._read_delimiter = None\n        self._read_regex = None\n        self._read_bytes = None\n        self._read_until_close = False\n        self._read_callback = None\n        self._read_future = None\n        self._streaming_callback = None\n        self._write_callback = None\n        self._write_future = None\n        self._close_callback = None\n        self._connect_callback = None\n        self._connect_future = None\n        self._connecting = False\n        self._state = None\n        self._pending_callbacks = 0\n        self._closed = False\n\n    def fileno(self):\n        \"\"\"Returns the file descriptor for this stream.\"\"\"\n        raise NotImplementedError()\n\n    def close_fd(self):\n        \"\"\"Closes the file underlying this stream.\n\n        ``close_fd`` is called by `BaseIOStream` and should not be called\n        elsewhere; other users should call `close` instead.\n        \"\"\"\n        raise NotImplementedError()\n\n    def write_to_fd(self, data):\n        \"\"\"Attempts to write ``data`` to the underlying file.\n\n        Returns the number of bytes written.\n        \"\"\"\n        raise NotImplementedError()\n\n    def read_from_fd(self):\n        \"\"\"Attempts to read from the underlying file.\n\n        Returns ``None`` if there was nothing to read (the socket\n        returned `~errno.EWOULDBLOCK` or equivalent), otherwise\n        returns the data.  When possible, should return no more than\n        ``self.read_chunk_size`` bytes at a time.\n        \"\"\"\n        raise NotImplementedError()\n\n    def get_fd_error(self):\n        \"\"\"Returns information about any error on the underlying file.\n\n        This method is called after the `.IOLoop` has signaled an error on the\n        file descriptor, and should return an Exception (such as `socket.error`\n        with additional information, or None if no such information is\n        available.\n        \"\"\"\n        return None\n\n    def read_until_regex(self, regex, callback=None):\n        \"\"\"Run ``callback`` when we read the given regex pattern.\n\n        The callback will get the data read (including the data that\n        matched the regex and anything that came before it) as an argument.\n        \"\"\"\n        future = self._set_read_callback(callback)\n        self._read_regex = re.compile(regex)\n        self._try_inline_read()\n        return future\n\n    def read_until(self, delimiter, callback=None):\n        \"\"\"Run ``callback`` when we read the given delimiter.\n\n        The callback will get the data read (including the delimiter)\n        as an argument.\n        \"\"\"\n        future = self._set_read_callback(callback)\n        self._read_delimiter = delimiter\n        self._try_inline_read()\n        return future\n\n    def read_bytes(self, num_bytes, callback=None, streaming_callback=None):\n        \"\"\"Run callback when we read the given number of bytes.\n\n        If a ``streaming_callback`` is given, it will be called with chunks\n        of data as they become available, and the argument to the final\n        ``callback`` will be empty.  Otherwise, the ``callback`` gets\n        the data as an argument.\n        \"\"\"\n        future = self._set_read_callback(callback)\n        assert isinstance(num_bytes, numbers.Integral)\n        self._read_bytes = num_bytes\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        self._try_inline_read()\n        return future\n\n    def read_until_close(self, callback=None, streaming_callback=None):\n        \"\"\"Reads all data from the socket until it is closed.\n\n        If a ``streaming_callback`` is given, it will be called with chunks\n        of data as they become available, and the argument to the final\n        ``callback`` will be empty.  Otherwise, the ``callback`` gets the\n        data as an argument.\n\n        Subject to ``max_buffer_size`` limit from `IOStream` constructor if\n        a ``streaming_callback`` is not used.\n        \"\"\"\n        future = self._set_read_callback(callback)\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        if self.closed():\n            if self._streaming_callback is not None:\n                self._run_callback(self._streaming_callback,\n                                   self._consume(self._read_buffer_size))\n            self._run_read_callback(self._consume(self._read_buffer_size))\n            return future\n        self._read_until_close = True\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        self._try_inline_read()\n        return future\n\n    def write(self, data, callback=None):\n        \"\"\"Write the given data to this stream.\n\n        If ``callback`` is given, we call it when all of the buffered write\n        data has been successfully written to the stream. If there was\n        previously buffered write data and an old write callback, that\n        callback is simply overwritten with this new callback.\n        \"\"\"\n        assert isinstance(data, bytes_type)\n        self._check_closed()\n        # We use bool(_write_buffer) as a proxy for write_buffer_size>0,\n        # so never put empty strings in the buffer.\n        if data:\n            # Break up large contiguous strings before inserting them in the\n            # write buffer, so we don't have to recopy the entire thing\n            # as we slice off pieces to send to the socket.\n            WRITE_BUFFER_CHUNK_SIZE = 128 * 1024\n            for i in range(0, len(data), WRITE_BUFFER_CHUNK_SIZE):\n                self._write_buffer.append(data[i:i + WRITE_BUFFER_CHUNK_SIZE])\n        if callback is not None:\n            self._write_callback = stack_context.wrap(callback)\n            future = None\n        else:\n            future = self._write_future = TracebackFuture()\n        if not self._connecting:\n            self._handle_write()\n            if self._write_buffer:\n                self._add_io_state(self.io_loop.WRITE)\n            self._maybe_add_error_listener()\n        return future\n\n    def set_close_callback(self, callback):\n        \"\"\"Call the given callback when the stream is closed.\"\"\"\n        self._close_callback = stack_context.wrap(callback)\n\n    def close(self, exc_info=False):\n        \"\"\"Close this stream.\n\n        If ``exc_info`` is true, set the ``error`` attribute to the current\n        exception from `sys.exc_info` (or if ``exc_info`` is a tuple,\n        use that instead of `sys.exc_info`).\n        \"\"\"\n        if not self.closed():\n            if exc_info:\n                if not isinstance(exc_info, tuple):\n                    exc_info = sys.exc_info()\n                if any(exc_info):\n                    self.error = exc_info[1]\n            if self._read_until_close:\n                if (self._streaming_callback is not None and\n                        self._read_buffer_size):\n                    self._run_callback(self._streaming_callback,\n                                       self._consume(self._read_buffer_size))\n                self._read_until_close = False\n                self._run_read_callback(self._consume(self._read_buffer_size))\n            if self._state is not None:\n                self.io_loop.remove_handler(self.fileno())\n                self._state = None\n            self.close_fd()\n            self._closed = True\n        self._maybe_run_close_callback()\n\n    def _maybe_run_close_callback(self):\n        # If there are pending callbacks, don't run the close callback\n        # until they're done (see _maybe_add_error_handler)\n        if self.closed() and self._pending_callbacks == 0:\n            futures = []\n            if self._read_future is not None:\n                futures.append(self._read_future)\n                self._read_future = None\n            if self._write_future is not None:\n                futures.append(self._write_future)\n                self._write_future = None\n            if self._connect_future is not None:\n                futures.append(self._connect_future)\n                self._connect_future = None\n            for future in futures:\n                future.set_exception(StreamClosedError())\n            if self._close_callback is not None:\n                cb = self._close_callback\n                self._close_callback = None\n                self._run_callback(cb)\n            # Delete any unfinished callbacks to break up reference cycles.\n            self._read_callback = self._write_callback = None\n            # Clear the buffers so they can be cleared immediately even\n            # if the IOStream object is kept alive by a reference cycle.\n            # TODO: Clear the read buffer too; it currently breaks some tests.\n            self._write_buffer = None\n\n    def reading(self):\n        \"\"\"Returns true if we are currently reading from the stream.\"\"\"\n        return self._read_callback is not None\n\n    def writing(self):\n        \"\"\"Returns true if we are currently writing to the stream.\"\"\"\n        return bool(self._write_buffer)\n\n    def closed(self):\n        \"\"\"Returns true if the stream has been closed.\"\"\"\n        return self._closed\n\n    def set_nodelay(self, value):\n        \"\"\"Sets the no-delay flag for this stream.\n\n        By default, data written to TCP streams may be held for a time\n        to make the most efficient use of bandwidth (according to\n        Nagle's algorithm).  The no-delay flag requests that data be\n        written as soon as possible, even if doing so would consume\n        additional bandwidth.\n\n        This flag is currently defined only for TCP-based ``IOStreams``.\n\n        .. versionadded:: 3.1\n        \"\"\"\n        pass\n\n    def _handle_events(self, fd, events):\n        if self.closed():\n            gen_log.warning(\"Got events for closed stream %s\", fd)\n            return\n        try:\n            if events & self.io_loop.READ:\n                self._handle_read()\n            if self.closed():\n                return\n            if events & self.io_loop.WRITE:\n                if self._connecting:\n                    self._handle_connect()\n                self._handle_write()\n            if self.closed():\n                return\n            if events & self.io_loop.ERROR:\n                self.error = self.get_fd_error()\n                # We may have queued up a user callback in _handle_read or\n                # _handle_write, so don't close the IOStream until those\n                # callbacks have had a chance to run.\n                self.io_loop.add_callback(self.close)\n                return\n            state = self.io_loop.ERROR\n            if self.reading():\n                state |= self.io_loop.READ\n            if self.writing():\n                state |= self.io_loop.WRITE\n            if state == self.io_loop.ERROR:\n                state |= self.io_loop.READ\n            if state != self._state:\n                assert self._state is not None, \\\n                    \"shouldn't happen: _handle_events without self._state\"\n                self._state = state\n                self.io_loop.update_handler(self.fileno(), self._state)\n        except Exception:\n            gen_log.error(\"Uncaught exception, closing connection.\",\n                          exc_info=True)\n            self.close(exc_info=True)\n            raise\n\n    def _run_callback(self, callback, *args):\n        def wrapper():\n            self._pending_callbacks -= 1\n            try:\n                callback(*args)\n            except Exception:\n                app_log.error(\"Uncaught exception, closing connection.\",\n                              exc_info=True)\n                # Close the socket on an uncaught exception from a user callback\n                # (It would eventually get closed when the socket object is\n                # gc'd, but we don't want to rely on gc happening before we\n                # run out of file descriptors)\n                self.close(exc_info=True)\n                # Re-raise the exception so that IOLoop.handle_callback_exception\n                # can see it and log the error\n                raise\n            self._maybe_add_error_listener()\n        # We schedule callbacks to be run on the next IOLoop iteration\n        # rather than running them directly for several reasons:\n        # * Prevents unbounded stack growth when a callback calls an\n        #   IOLoop operation that immediately runs another callback\n        # * Provides a predictable execution context for e.g.\n        #   non-reentrant mutexes\n        # * Ensures that the try/except in wrapper() is run outside\n        #   of the application's StackContexts\n        with stack_context.NullContext():\n            # stack_context was already captured in callback, we don't need to\n            # capture it again for IOStream's wrapper.  This is especially\n            # important if the callback was pre-wrapped before entry to\n            # IOStream (as in HTTPConnection._header_callback), as we could\n            # capture and leak the wrong context here.\n            self._pending_callbacks += 1\n            self.io_loop.add_callback(wrapper)\n\n    def _handle_read(self):\n        try:\n            try:\n                # Pretend to have a pending callback so that an EOF in\n                # _read_to_buffer doesn't trigger an immediate close\n                # callback.  At the end of this method we'll either\n                # estabilsh a real pending callback via\n                # _read_from_buffer or run the close callback.\n                #\n                # We need two try statements here so that\n                # pending_callbacks is decremented before the `except`\n                # clause below (which calls `close` and does need to\n                # trigger the callback)\n                self._pending_callbacks += 1\n                while not self.closed():\n                    # Read from the socket until we get EWOULDBLOCK or equivalent.\n                    # SSL sockets do some internal buffering, and if the data is\n                    # sitting in the SSL object's buffer select() and friends\n                    # can't see it; the only way to find out if it's there is to\n                    # try to read it.\n                    if self._read_to_buffer() == 0:\n                        break\n            finally:\n                self._pending_callbacks -= 1\n        except Exception:\n            gen_log.warning(\"error on read\", exc_info=True)\n            self.close(exc_info=True)\n            return\n        if self._read_from_buffer():\n            return\n        else:\n            self._maybe_run_close_callback()\n\n    def _set_read_callback(self, callback):\n        assert self._read_callback is None, \"Already reading\"\n        assert self._read_future is None, \"Already reading\"\n        if callback is not None:\n            self._read_callback = stack_context.wrap(callback)\n        else:\n            self._read_future = TracebackFuture()\n        return self._read_future\n\n    def _run_read_callback(self, data):\n        self._streaming_callback = None\n        if self._read_future is not None:\n            future = self._read_future\n            self._read_future = None\n            future.set_result(data)\n        if self._read_callback is not None:\n            callback = self._read_callback\n            self._read_callback = None\n            self._run_callback(callback, data)\n        else:\n            # If we scheduled a callback, we will add the error listener\n            # afterwards.  If we didn't, we have to do it now.\n            self._maybe_add_error_listener()\n\n    def _try_inline_read(self):\n        \"\"\"Attempt to complete the current read operation from buffered data.\n\n        If the read can be completed without blocking, schedules the\n        read callback on the next IOLoop iteration; otherwise starts\n        listening for reads on the socket.\n        \"\"\"\n        # See if we've already got the data from a previous read\n        if self._read_from_buffer():\n            return\n        self._check_closed()\n        try:\n            try:\n                # See comments in _handle_read about incrementing _pending_callbacks\n                self._pending_callbacks += 1\n                while not self.closed():\n                    if self._read_to_buffer() == 0:\n                        break\n            finally:\n                self._pending_callbacks -= 1\n        except Exception:\n            # If there was an in _read_to_buffer, we called close() already,\n            # but couldn't run the close callback because of _pending_callbacks.\n            # Before we escape from this function, run the close callback if\n            # applicable.\n            self._maybe_run_close_callback()\n            raise\n        if self._read_from_buffer():\n            return\n        self._maybe_add_error_listener()\n\n    def _read_to_buffer(self):\n        \"\"\"Reads from the socket and appends the result to the read buffer.\n\n        Returns the number of bytes read.  Returns 0 if there is nothing\n        to read (i.e. the read returns EWOULDBLOCK or equivalent).  On\n        error closes the socket and raises an exception.\n        \"\"\"\n        try:\n            chunk = self.read_from_fd()\n        except (socket.error, IOError, OSError) as e:\n            # ssl.SSLError is a subclass of socket.error\n            if e.args[0] in _ERRNO_CONNRESET:\n                # Treat ECONNRESET as a connection close rather than\n                # an error to minimize log spam  (the exception will\n                # be available on self.error for apps that care).\n                self.close(exc_info=True)\n                return\n            self.close(exc_info=True)\n            raise\n        if chunk is None:\n            return 0\n        self._read_buffer.append(chunk)\n        self._read_buffer_size += len(chunk)\n        if self._read_buffer_size >= self.max_buffer_size:\n            gen_log.error(\"Reached maximum read buffer size\")\n            self.close()\n            raise IOError(\"Reached maximum read buffer size\")\n        return len(chunk)\n\n    def _read_from_buffer(self):\n        \"\"\"Attempts to complete the currently-pending read from the buffer.\n\n        Returns True if the read was completed.\n        \"\"\"\n        if self._streaming_callback is not None and self._read_buffer_size:\n            bytes_to_consume = self._read_buffer_size\n            if self._read_bytes is not None:\n                bytes_to_consume = min(self._read_bytes, bytes_to_consume)\n                self._read_bytes -= bytes_to_consume\n            self._run_callback(self._streaming_callback,\n                               self._consume(bytes_to_consume))\n        if self._read_bytes is not None and self._read_buffer_size >= self._read_bytes:\n            num_bytes = self._read_bytes\n            self._read_bytes = None\n            self._run_read_callback(self._consume(num_bytes))\n            return True\n        elif self._read_delimiter is not None:\n            # Multi-byte delimiters (e.g. '\\r\\n') may straddle two\n            # chunks in the read buffer, so we can't easily find them\n            # without collapsing the buffer.  However, since protocols\n            # using delimited reads (as opposed to reads of a known\n            # length) tend to be \"line\" oriented, the delimiter is likely\n            # to be in the first few chunks.  Merge the buffer gradually\n            # since large merges are relatively expensive and get undone in\n            # consume().\n            if self._read_buffer:\n                while True:\n                    loc = self._read_buffer[0].find(self._read_delimiter)\n                    if loc != -1:\n                        delimiter_len = len(self._read_delimiter)\n                        self._read_delimiter = None\n                        self._run_read_callback(\n                            self._consume(loc + delimiter_len))\n                        return True\n                    if len(self._read_buffer) == 1:\n                        break\n                    _double_prefix(self._read_buffer)\n        elif self._read_regex is not None:\n            if self._read_buffer:\n                while True:\n                    m = self._read_regex.search(self._read_buffer[0])\n                    if m is not None:\n                        self._read_regex = None\n                        self._run_read_callback(self._consume(m.end()))\n                        return True\n                    if len(self._read_buffer) == 1:\n                        break\n                    _double_prefix(self._read_buffer)\n        return False\n\n    def _handle_write(self):\n        while self._write_buffer:\n            try:\n                if not self._write_buffer_frozen:\n                    # On windows, socket.send blows up if given a\n                    # write buffer that's too large, instead of just\n                    # returning the number of bytes it was able to\n                    # process.  Therefore we must not call socket.send\n                    # with more than 128KB at a time.\n                    _merge_prefix(self._write_buffer, 128 * 1024)\n                num_bytes = self.write_to_fd(self._write_buffer[0])\n                if num_bytes == 0:\n                    # With OpenSSL, if we couldn't write the entire buffer,\n                    # the very same string object must be used on the\n                    # next call to send.  Therefore we suppress\n                    # merging the write buffer after an incomplete send.\n                    # A cleaner solution would be to set\n                    # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, but this is\n                    # not yet accessible from python\n                    # (http://bugs.python.org/issue8240)\n                    self._write_buffer_frozen = True\n                    break\n                self._write_buffer_frozen = False\n                _merge_prefix(self._write_buffer, num_bytes)\n                self._write_buffer.popleft()\n            except (socket.error, IOError, OSError) as e:\n                if e.args[0] in _ERRNO_WOULDBLOCK:\n                    self._write_buffer_frozen = True\n                    break\n                else:\n                    if e.args[0] not in _ERRNO_CONNRESET:\n                        # Broken pipe errors are usually caused by connection\n                        # reset, and its better to not log EPIPE errors to\n                        # minimize log spam\n                        gen_log.warning(\"Write error on %s: %s\",\n                                        self.fileno(), e)\n                    self.close(exc_info=True)\n                    return\n        if not self._write_buffer:\n            if self._write_callback:\n                callback = self._write_callback\n                self._write_callback = None\n                self._run_callback(callback)\n            if self._write_future:\n                future = self._write_future\n                self._write_future = None\n                future.set_result(None)\n\n    def _consume(self, loc):\n        if loc == 0:\n            return b\"\"\n        _merge_prefix(self._read_buffer, loc)\n        self._read_buffer_size -= loc\n        return self._read_buffer.popleft()\n\n    def _check_closed(self):\n        if self.closed():\n            raise StreamClosedError(\"Stream is closed\")\n\n    def _maybe_add_error_listener(self):\n        if self._state is None and self._pending_callbacks == 0:\n            if self.closed():\n                self._maybe_run_close_callback()\n            else:\n                self._add_io_state(ioloop.IOLoop.READ)\n\n    def _add_io_state(self, state):\n        \"\"\"Adds `state` (IOLoop.{READ,WRITE} flags) to our event handler.\n\n        Implementation notes: Reads and writes have a fast path and a\n        slow path.  The fast path reads synchronously from socket\n        buffers, while the slow path uses `_add_io_state` to schedule\n        an IOLoop callback.  Note that in both cases, the callback is\n        run asynchronously with `_run_callback`.\n\n        To detect closed connections, we must have called\n        `_add_io_state` at some point, but we want to delay this as\n        much as possible so we don't have to set an `IOLoop.ERROR`\n        listener that will be overwritten by the next slow-path\n        operation.  As long as there are callbacks scheduled for\n        fast-path ops, those callbacks may do more reads.\n        If a sequence of fast-path ops do not end in a slow-path op,\n        (e.g. for an @asynchronous long-poll request), we must add\n        the error handler.  This is done in `_run_callback` and `write`\n        (since the write callback is optional so we can have a\n        fast-path write with no `_run_callback`)\n        \"\"\"\n        if self.closed():\n            # connection has been closed, so there can be no future events\n            return\n        if self._state is None:\n            self._state = ioloop.IOLoop.ERROR | state\n            with stack_context.NullContext():\n                self.io_loop.add_handler(\n                    self.fileno(), self._handle_events, self._state)\n        elif not self._state & state:\n            self._state = self._state | state\n            self.io_loop.update_handler(self.fileno(), self._state)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 442,
                            "end_lineno": 455,
                            "parent": {
                                "file_name": "tornado/iostream.py",
                                "type": "class",
                                "name": "BaseIOStream",
                                "content": "class BaseIOStream(object):\n    \"\"\"A utility class to write to and read from a non-blocking file or socket.\n\n    We support a non-blocking ``write()`` and a family of ``read_*()`` methods.\n    All of the methods take callbacks (since writing and reading are\n    non-blocking and asynchronous).\n\n    When a stream is closed due to an error, the IOStream's ``error``\n    attribute contains the exception object.\n\n    Subclasses must implement `fileno`, `close_fd`, `write_to_fd`,\n    `read_from_fd`, and optionally `get_fd_error`.\n    \"\"\"\n    def __init__(self, io_loop=None, max_buffer_size=None,\n                 read_chunk_size=4096):\n        self.io_loop = io_loop or ioloop.IOLoop.current()\n        self.max_buffer_size = max_buffer_size or 104857600\n        self.read_chunk_size = read_chunk_size\n        self.error = None\n        self._read_buffer = collections.deque()\n        self._write_buffer = collections.deque()\n        self._read_buffer_size = 0\n        self._write_buffer_frozen = False\n        self._read_delimiter = None\n        self._read_regex = None\n        self._read_bytes = None\n        self._read_until_close = False\n        self._read_callback = None\n        self._read_future = None\n        self._streaming_callback = None\n        self._write_callback = None\n        self._write_future = None\n        self._close_callback = None\n        self._connect_callback = None\n        self._connect_future = None\n        self._connecting = False\n        self._state = None\n        self._pending_callbacks = 0\n        self._closed = False\n\n    def fileno(self):\n        \"\"\"Returns the file descriptor for this stream.\"\"\"\n        raise NotImplementedError()\n\n    def close_fd(self):\n        \"\"\"Closes the file underlying this stream.\n\n        ``close_fd`` is called by `BaseIOStream` and should not be called\n        elsewhere; other users should call `close` instead.\n        \"\"\"\n        raise NotImplementedError()\n\n    def write_to_fd(self, data):\n        \"\"\"Attempts to write ``data`` to the underlying file.\n\n        Returns the number of bytes written.\n        \"\"\"\n        raise NotImplementedError()\n\n    def read_from_fd(self):\n        \"\"\"Attempts to read from the underlying file.\n\n        Returns ``None`` if there was nothing to read (the socket\n        returned `~errno.EWOULDBLOCK` or equivalent), otherwise\n        returns the data.  When possible, should return no more than\n        ``self.read_chunk_size`` bytes at a time.\n        \"\"\"\n        raise NotImplementedError()\n\n    def get_fd_error(self):\n        \"\"\"Returns information about any error on the underlying file.\n\n        This method is called after the `.IOLoop` has signaled an error on the\n        file descriptor, and should return an Exception (such as `socket.error`\n        with additional information, or None if no such information is\n        available.\n        \"\"\"\n        return None\n\n    def read_until_regex(self, regex, callback=None):\n        \"\"\"Run ``callback`` when we read the given regex pattern.\n\n        The callback will get the data read (including the data that\n        matched the regex and anything that came before it) as an argument.\n        \"\"\"\n        future = self._set_read_callback(callback)\n        self._read_regex = re.compile(regex)\n        self._try_inline_read()\n        return future\n\n    def read_until(self, delimiter, callback=None):\n        \"\"\"Run ``callback`` when we read the given delimiter.\n\n        The callback will get the data read (including the delimiter)\n        as an argument.\n        \"\"\"\n        future = self._set_read_callback(callback)\n        self._read_delimiter = delimiter\n        self._try_inline_read()\n        return future\n\n    def read_bytes(self, num_bytes, callback=None, streaming_callback=None):\n        \"\"\"Run callback when we read the given number of bytes.\n\n        If a ``streaming_callback`` is given, it will be called with chunks\n        of data as they become available, and the argument to the final\n        ``callback`` will be empty.  Otherwise, the ``callback`` gets\n        the data as an argument.\n        \"\"\"\n        future = self._set_read_callback(callback)\n        assert isinstance(num_bytes, numbers.Integral)\n        self._read_bytes = num_bytes\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        self._try_inline_read()\n        return future\n\n    def read_until_close(self, callback=None, streaming_callback=None):\n        \"\"\"Reads all data from the socket until it is closed.\n\n        If a ``streaming_callback`` is given, it will be called with chunks\n        of data as they become available, and the argument to the final\n        ``callback`` will be empty.  Otherwise, the ``callback`` gets the\n        data as an argument.\n\n        Subject to ``max_buffer_size`` limit from `IOStream` constructor if\n        a ``streaming_callback`` is not used.\n        \"\"\"\n        future = self._set_read_callback(callback)\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        if self.closed():\n            if self._streaming_callback is not None:\n                self._run_callback(self._streaming_callback,\n                                   self._consume(self._read_buffer_size))\n            self._run_read_callback(self._consume(self._read_buffer_size))\n            return future\n        self._read_until_close = True\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        self._try_inline_read()\n        return future\n\n    def write(self, data, callback=None):\n        \"\"\"Write the given data to this stream.\n\n        If ``callback`` is given, we call it when all of the buffered write\n        data has been successfully written to the stream. If there was\n        previously buffered write data and an old write callback, that\n        callback is simply overwritten with this new callback.\n        \"\"\"\n        assert isinstance(data, bytes_type)\n        self._check_closed()\n        # We use bool(_write_buffer) as a proxy for write_buffer_size>0,\n        # so never put empty strings in the buffer.\n        if data:\n            # Break up large contiguous strings before inserting them in the\n            # write buffer, so we don't have to recopy the entire thing\n            # as we slice off pieces to send to the socket.\n            WRITE_BUFFER_CHUNK_SIZE = 128 * 1024\n            for i in range(0, len(data), WRITE_BUFFER_CHUNK_SIZE):\n                self._write_buffer.append(data[i:i + WRITE_BUFFER_CHUNK_SIZE])\n        if callback is not None:\n            self._write_callback = stack_context.wrap(callback)\n            future = None\n        else:\n            future = self._write_future = TracebackFuture()\n        if not self._connecting:\n            self._handle_write()\n            if self._write_buffer:\n                self._add_io_state(self.io_loop.WRITE)\n            self._maybe_add_error_listener()\n        return future\n\n    def set_close_callback(self, callback):\n        \"\"\"Call the given callback when the stream is closed.\"\"\"\n        self._close_callback = stack_context.wrap(callback)\n\n    def close(self, exc_info=False):\n        \"\"\"Close this stream.\n\n        If ``exc_info`` is true, set the ``error`` attribute to the current\n        exception from `sys.exc_info` (or if ``exc_info`` is a tuple,\n        use that instead of `sys.exc_info`).\n        \"\"\"\n        if not self.closed():\n            if exc_info:\n                if not isinstance(exc_info, tuple):\n                    exc_info = sys.exc_info()\n                if any(exc_info):\n                    self.error = exc_info[1]\n            if self._read_until_close:\n                if (self._streaming_callback is not None and\n                        self._read_buffer_size):\n                    self._run_callback(self._streaming_callback,\n                                       self._consume(self._read_buffer_size))\n                self._read_until_close = False\n                self._run_read_callback(self._consume(self._read_buffer_size))\n            if self._state is not None:\n                self.io_loop.remove_handler(self.fileno())\n                self._state = None\n            self.close_fd()\n            self._closed = True\n        self._maybe_run_close_callback()\n\n    def _maybe_run_close_callback(self):\n        # If there are pending callbacks, don't run the close callback\n        # until they're done (see _maybe_add_error_handler)\n        if self.closed() and self._pending_callbacks == 0:\n            futures = []\n            if self._read_future is not None:\n                futures.append(self._read_future)\n                self._read_future = None\n            if self._write_future is not None:\n                futures.append(self._write_future)\n                self._write_future = None\n            if self._connect_future is not None:\n                futures.append(self._connect_future)\n                self._connect_future = None\n            for future in futures:\n                future.set_exception(StreamClosedError())\n            if self._close_callback is not None:\n                cb = self._close_callback\n                self._close_callback = None\n                self._run_callback(cb)\n            # Delete any unfinished callbacks to break up reference cycles.\n            self._read_callback = self._write_callback = None\n            # Clear the buffers so they can be cleared immediately even\n            # if the IOStream object is kept alive by a reference cycle.\n            # TODO: Clear the read buffer too; it currently breaks some tests.\n            self._write_buffer = None\n\n    def reading(self):\n        \"\"\"Returns true if we are currently reading from the stream.\"\"\"\n        return self._read_callback is not None\n\n    def writing(self):\n        \"\"\"Returns true if we are currently writing to the stream.\"\"\"\n        return bool(self._write_buffer)\n\n    def closed(self):\n        \"\"\"Returns true if the stream has been closed.\"\"\"\n        return self._closed\n\n    def set_nodelay(self, value):\n        \"\"\"Sets the no-delay flag for this stream.\n\n        By default, data written to TCP streams may be held for a time\n        to make the most efficient use of bandwidth (according to\n        Nagle's algorithm).  The no-delay flag requests that data be\n        written as soon as possible, even if doing so would consume\n        additional bandwidth.\n\n        This flag is currently defined only for TCP-based ``IOStreams``.\n\n        .. versionadded:: 3.1\n        \"\"\"\n        pass\n\n    def _handle_events(self, fd, events):\n        if self.closed():\n            gen_log.warning(\"Got events for closed stream %s\", fd)\n            return\n        try:\n            if events & self.io_loop.READ:\n                self._handle_read()\n            if self.closed():\n                return\n            if events & self.io_loop.WRITE:\n                if self._connecting:\n                    self._handle_connect()\n                self._handle_write()\n            if self.closed():\n                return\n            if events & self.io_loop.ERROR:\n                self.error = self.get_fd_error()\n                # We may have queued up a user callback in _handle_read or\n                # _handle_write, so don't close the IOStream until those\n                # callbacks have had a chance to run.\n                self.io_loop.add_callback(self.close)\n                return\n            state = self.io_loop.ERROR\n            if self.reading():\n                state |= self.io_loop.READ\n            if self.writing():\n                state |= self.io_loop.WRITE\n            if state == self.io_loop.ERROR:\n                state |= self.io_loop.READ\n            if state != self._state:\n                assert self._state is not None, \\\n                    \"shouldn't happen: _handle_events without self._state\"\n                self._state = state\n                self.io_loop.update_handler(self.fileno(), self._state)\n        except Exception:\n            gen_log.error(\"Uncaught exception, closing connection.\",\n                          exc_info=True)\n            self.close(exc_info=True)\n            raise\n\n    def _run_callback(self, callback, *args):\n        def wrapper():\n            self._pending_callbacks -= 1\n            try:\n                callback(*args)\n            except Exception:\n                app_log.error(\"Uncaught exception, closing connection.\",\n                              exc_info=True)\n                # Close the socket on an uncaught exception from a user callback\n                # (It would eventually get closed when the socket object is\n                # gc'd, but we don't want to rely on gc happening before we\n                # run out of file descriptors)\n                self.close(exc_info=True)\n                # Re-raise the exception so that IOLoop.handle_callback_exception\n                # can see it and log the error\n                raise\n            self._maybe_add_error_listener()\n        # We schedule callbacks to be run on the next IOLoop iteration\n        # rather than running them directly for several reasons:\n        # * Prevents unbounded stack growth when a callback calls an\n        #   IOLoop operation that immediately runs another callback\n        # * Provides a predictable execution context for e.g.\n        #   non-reentrant mutexes\n        # * Ensures that the try/except in wrapper() is run outside\n        #   of the application's StackContexts\n        with stack_context.NullContext():\n            # stack_context was already captured in callback, we don't need to\n            # capture it again for IOStream's wrapper.  This is especially\n            # important if the callback was pre-wrapped before entry to\n            # IOStream (as in HTTPConnection._header_callback), as we could\n            # capture and leak the wrong context here.\n            self._pending_callbacks += 1\n            self.io_loop.add_callback(wrapper)\n\n    def _handle_read(self):\n        try:\n            try:\n                # Pretend to have a pending callback so that an EOF in\n                # _read_to_buffer doesn't trigger an immediate close\n                # callback.  At the end of this method we'll either\n                # estabilsh a real pending callback via\n                # _read_from_buffer or run the close callback.\n                #\n                # We need two try statements here so that\n                # pending_callbacks is decremented before the `except`\n                # clause below (which calls `close` and does need to\n                # trigger the callback)\n                self._pending_callbacks += 1\n                while not self.closed():\n                    # Read from the socket until we get EWOULDBLOCK or equivalent.\n                    # SSL sockets do some internal buffering, and if the data is\n                    # sitting in the SSL object's buffer select() and friends\n                    # can't see it; the only way to find out if it's there is to\n                    # try to read it.\n                    if self._read_to_buffer() == 0:\n                        break\n            finally:\n                self._pending_callbacks -= 1\n        except Exception:\n            gen_log.warning(\"error on read\", exc_info=True)\n            self.close(exc_info=True)\n            return\n        if self._read_from_buffer():\n            return\n        else:\n            self._maybe_run_close_callback()\n\n    def _set_read_callback(self, callback):\n        assert self._read_callback is None, \"Already reading\"\n        assert self._read_future is None, \"Already reading\"\n        if callback is not None:\n            self._read_callback = stack_context.wrap(callback)\n        else:\n            self._read_future = TracebackFuture()\n        return self._read_future\n\n    def _run_read_callback(self, data):\n        self._streaming_callback = None\n        if self._read_future is not None:\n            future = self._read_future\n            self._read_future = None\n            future.set_result(data)\n        if self._read_callback is not None:\n            callback = self._read_callback\n            self._read_callback = None\n            self._run_callback(callback, data)\n        else:\n            # If we scheduled a callback, we will add the error listener\n            # afterwards.  If we didn't, we have to do it now.\n            self._maybe_add_error_listener()\n\n    def _try_inline_read(self):\n        \"\"\"Attempt to complete the current read operation from buffered data.\n\n        If the read can be completed without blocking, schedules the\n        read callback on the next IOLoop iteration; otherwise starts\n        listening for reads on the socket.\n        \"\"\"\n        # See if we've already got the data from a previous read\n        if self._read_from_buffer():\n            return\n        self._check_closed()\n        try:\n            try:\n                # See comments in _handle_read about incrementing _pending_callbacks\n                self._pending_callbacks += 1\n                while not self.closed():\n                    if self._read_to_buffer() == 0:\n                        break\n            finally:\n                self._pending_callbacks -= 1\n        except Exception:\n            # If there was an in _read_to_buffer, we called close() already,\n            # but couldn't run the close callback because of _pending_callbacks.\n            # Before we escape from this function, run the close callback if\n            # applicable.\n            self._maybe_run_close_callback()\n            raise\n        if self._read_from_buffer():\n            return\n        self._maybe_add_error_listener()\n\n    def _read_to_buffer(self):\n        \"\"\"Reads from the socket and appends the result to the read buffer.\n\n        Returns the number of bytes read.  Returns 0 if there is nothing\n        to read (i.e. the read returns EWOULDBLOCK or equivalent).  On\n        error closes the socket and raises an exception.\n        \"\"\"\n        try:\n            chunk = self.read_from_fd()\n        except (socket.error, IOError, OSError) as e:\n            # ssl.SSLError is a subclass of socket.error\n            if e.args[0] in _ERRNO_CONNRESET:\n                # Treat ECONNRESET as a connection close rather than\n                # an error to minimize log spam  (the exception will\n                # be available on self.error for apps that care).\n                self.close(exc_info=True)\n                return\n            self.close(exc_info=True)\n            raise\n        if chunk is None:\n            return 0\n        self._read_buffer.append(chunk)\n        self._read_buffer_size += len(chunk)\n        if self._read_buffer_size >= self.max_buffer_size:\n            gen_log.error(\"Reached maximum read buffer size\")\n            self.close()\n            raise IOError(\"Reached maximum read buffer size\")\n        return len(chunk)\n\n    def _read_from_buffer(self):\n        \"\"\"Attempts to complete the currently-pending read from the buffer.\n\n        Returns True if the read was completed.\n        \"\"\"\n        if self._streaming_callback is not None and self._read_buffer_size:\n            bytes_to_consume = self._read_buffer_size\n            if self._read_bytes is not None:\n                bytes_to_consume = min(self._read_bytes, bytes_to_consume)\n                self._read_bytes -= bytes_to_consume\n            self._run_callback(self._streaming_callback,\n                               self._consume(bytes_to_consume))\n        if self._read_bytes is not None and self._read_buffer_size >= self._read_bytes:\n            num_bytes = self._read_bytes\n            self._read_bytes = None\n            self._run_read_callback(self._consume(num_bytes))\n            return True\n        elif self._read_delimiter is not None:\n            # Multi-byte delimiters (e.g. '\\r\\n') may straddle two\n            # chunks in the read buffer, so we can't easily find them\n            # without collapsing the buffer.  However, since protocols\n            # using delimited reads (as opposed to reads of a known\n            # length) tend to be \"line\" oriented, the delimiter is likely\n            # to be in the first few chunks.  Merge the buffer gradually\n            # since large merges are relatively expensive and get undone in\n            # consume().\n            if self._read_buffer:\n                while True:\n                    loc = self._read_buffer[0].find(self._read_delimiter)\n                    if loc != -1:\n                        delimiter_len = len(self._read_delimiter)\n                        self._read_delimiter = None\n                        self._run_read_callback(\n                            self._consume(loc + delimiter_len))\n                        return True\n                    if len(self._read_buffer) == 1:\n                        break\n                    _double_prefix(self._read_buffer)\n        elif self._read_regex is not None:\n            if self._read_buffer:\n                while True:\n                    m = self._read_regex.search(self._read_buffer[0])\n                    if m is not None:\n                        self._read_regex = None\n                        self._run_read_callback(self._consume(m.end()))\n                        return True\n                    if len(self._read_buffer) == 1:\n                        break\n                    _double_prefix(self._read_buffer)\n        return False\n\n    def _handle_write(self):\n        while self._write_buffer:\n            try:\n                if not self._write_buffer_frozen:\n                    # On windows, socket.send blows up if given a\n                    # write buffer that's too large, instead of just\n                    # returning the number of bytes it was able to\n                    # process.  Therefore we must not call socket.send\n                    # with more than 128KB at a time.\n                    _merge_prefix(self._write_buffer, 128 * 1024)\n                num_bytes = self.write_to_fd(self._write_buffer[0])\n                if num_bytes == 0:\n                    # With OpenSSL, if we couldn't write the entire buffer,\n                    # the very same string object must be used on the\n                    # next call to send.  Therefore we suppress\n                    # merging the write buffer after an incomplete send.\n                    # A cleaner solution would be to set\n                    # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, but this is\n                    # not yet accessible from python\n                    # (http://bugs.python.org/issue8240)\n                    self._write_buffer_frozen = True\n                    break\n                self._write_buffer_frozen = False\n                _merge_prefix(self._write_buffer, num_bytes)\n                self._write_buffer.popleft()\n            except (socket.error, IOError, OSError) as e:\n                if e.args[0] in _ERRNO_WOULDBLOCK:\n                    self._write_buffer_frozen = True\n                    break\n                else:\n                    if e.args[0] not in _ERRNO_CONNRESET:\n                        # Broken pipe errors are usually caused by connection\n                        # reset, and its better to not log EPIPE errors to\n                        # minimize log spam\n                        gen_log.warning(\"Write error on %s: %s\",\n                                        self.fileno(), e)\n                    self.close(exc_info=True)\n                    return\n        if not self._write_buffer:\n            if self._write_callback:\n                callback = self._write_callback\n                self._write_callback = None\n                self._run_callback(callback)\n            if self._write_future:\n                future = self._write_future\n                self._write_future = None\n                future.set_result(None)\n\n    def _consume(self, loc):\n        if loc == 0:\n            return b\"\"\n        _merge_prefix(self._read_buffer, loc)\n        self._read_buffer_size -= loc\n        return self._read_buffer.popleft()\n\n    def _check_closed(self):\n        if self.closed():\n            raise StreamClosedError(\"Stream is closed\")\n\n    def _maybe_add_error_listener(self):\n        if self._state is None and self._pending_callbacks == 0:\n            if self.closed():\n                self._maybe_run_close_callback()\n            else:\n                self._add_io_state(ioloop.IOLoop.READ)\n\n    def _add_io_state(self, state):\n        \"\"\"Adds `state` (IOLoop.{READ,WRITE} flags) to our event handler.\n\n        Implementation notes: Reads and writes have a fast path and a\n        slow path.  The fast path reads synchronously from socket\n        buffers, while the slow path uses `_add_io_state` to schedule\n        an IOLoop callback.  Note that in both cases, the callback is\n        run asynchronously with `_run_callback`.\n\n        To detect closed connections, we must have called\n        `_add_io_state` at some point, but we want to delay this as\n        much as possible so we don't have to set an `IOLoop.ERROR`\n        listener that will be overwritten by the next slow-path\n        operation.  As long as there are callbacks scheduled for\n        fast-path ops, those callbacks may do more reads.\n        If a sequence of fast-path ops do not end in a slow-path op,\n        (e.g. for an @asynchronous long-poll request), we must add\n        the error handler.  This is done in `_run_callback` and `write`\n        (since the write callback is optional so we can have a\n        fast-path write with no `_run_callback`)\n        \"\"\"\n        if self.closed():\n            # connection has been closed, so there can be no future events\n            return\n        if self._state is None:\n            self._state = ioloop.IOLoop.ERROR | state\n            with stack_context.NullContext():\n                self.io_loop.add_handler(\n                    self.fileno(), self._handle_events, self._state)\n        elif not self._state & state:\n            self._state = self._state | state\n            self.io_loop.update_handler(self.fileno(), self._state)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 70,
                                "end_lineno": 665,
                                "parent": null
                            }
                        },
                        {
                            "file_name": "tornado/iostream.py",
                            "type": "class",
                            "name": "BaseIOStream",
                            "content": "class BaseIOStream(object):\n    \"\"\"A utility class to write to and read from a non-blocking file or socket.\n\n    We support a non-blocking ``write()`` and a family of ``read_*()`` methods.\n    All of the methods take callbacks (since writing and reading are\n    non-blocking and asynchronous).\n\n    When a stream is closed due to an error, the IOStream's ``error``\n    attribute contains the exception object.\n\n    Subclasses must implement `fileno`, `close_fd`, `write_to_fd`,\n    `read_from_fd`, and optionally `get_fd_error`.\n    \"\"\"\n    def __init__(self, io_loop=None, max_buffer_size=None,\n                 read_chunk_size=4096):\n        self.io_loop = io_loop or ioloop.IOLoop.current()\n        self.max_buffer_size = max_buffer_size or 104857600\n        self.read_chunk_size = read_chunk_size\n        self.error = None\n        self._read_buffer = collections.deque()\n        self._write_buffer = collections.deque()\n        self._read_buffer_size = 0\n        self._write_buffer_frozen = False\n        self._read_delimiter = None\n        self._read_regex = None\n        self._read_bytes = None\n        self._read_until_close = False\n        self._read_callback = None\n        self._read_future = None\n        self._streaming_callback = None\n        self._write_callback = None\n        self._write_future = None\n        self._close_callback = None\n        self._connect_callback = None\n        self._connect_future = None\n        self._connecting = False\n        self._state = None\n        self._pending_callbacks = 0\n        self._closed = False\n\n    def fileno(self):\n        \"\"\"Returns the file descriptor for this stream.\"\"\"\n        raise NotImplementedError()\n\n    def close_fd(self):\n        \"\"\"Closes the file underlying this stream.\n\n        ``close_fd`` is called by `BaseIOStream` and should not be called\n        elsewhere; other users should call `close` instead.\n        \"\"\"\n        raise NotImplementedError()\n\n    def write_to_fd(self, data):\n        \"\"\"Attempts to write ``data`` to the underlying file.\n\n        Returns the number of bytes written.\n        \"\"\"\n        raise NotImplementedError()\n\n    def read_from_fd(self):\n        \"\"\"Attempts to read from the underlying file.\n\n        Returns ``None`` if there was nothing to read (the socket\n        returned `~errno.EWOULDBLOCK` or equivalent), otherwise\n        returns the data.  When possible, should return no more than\n        ``self.read_chunk_size`` bytes at a time.\n        \"\"\"\n        raise NotImplementedError()\n\n    def get_fd_error(self):\n        \"\"\"Returns information about any error on the underlying file.\n\n        This method is called after the `.IOLoop` has signaled an error on the\n        file descriptor, and should return an Exception (such as `socket.error`\n        with additional information, or None if no such information is\n        available.\n        \"\"\"\n        return None\n\n    def read_until_regex(self, regex, callback=None):\n        \"\"\"Run ``callback`` when we read the given regex pattern.\n\n        The callback will get the data read (including the data that\n        matched the regex and anything that came before it) as an argument.\n        \"\"\"\n        future = self._set_read_callback(callback)\n        self._read_regex = re.compile(regex)\n        self._try_inline_read()\n        return future\n\n    def read_until(self, delimiter, callback=None):\n        \"\"\"Run ``callback`` when we read the given delimiter.\n\n        The callback will get the data read (including the delimiter)\n        as an argument.\n        \"\"\"\n        future = self._set_read_callback(callback)\n        self._read_delimiter = delimiter\n        self._try_inline_read()\n        return future\n\n    def read_bytes(self, num_bytes, callback=None, streaming_callback=None):\n        \"\"\"Run callback when we read the given number of bytes.\n\n        If a ``streaming_callback`` is given, it will be called with chunks\n        of data as they become available, and the argument to the final\n        ``callback`` will be empty.  Otherwise, the ``callback`` gets\n        the data as an argument.\n        \"\"\"\n        future = self._set_read_callback(callback)\n        assert isinstance(num_bytes, numbers.Integral)\n        self._read_bytes = num_bytes\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        self._try_inline_read()\n        return future\n\n    def read_until_close(self, callback=None, streaming_callback=None):\n        \"\"\"Reads all data from the socket until it is closed.\n\n        If a ``streaming_callback`` is given, it will be called with chunks\n        of data as they become available, and the argument to the final\n        ``callback`` will be empty.  Otherwise, the ``callback`` gets the\n        data as an argument.\n\n        Subject to ``max_buffer_size`` limit from `IOStream` constructor if\n        a ``streaming_callback`` is not used.\n        \"\"\"\n        future = self._set_read_callback(callback)\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        if self.closed():\n            if self._streaming_callback is not None:\n                self._run_callback(self._streaming_callback,\n                                   self._consume(self._read_buffer_size))\n            self._run_read_callback(self._consume(self._read_buffer_size))\n            return future\n        self._read_until_close = True\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        self._try_inline_read()\n        return future\n\n    def write(self, data, callback=None):\n        \"\"\"Write the given data to this stream.\n\n        If ``callback`` is given, we call it when all of the buffered write\n        data has been successfully written to the stream. If there was\n        previously buffered write data and an old write callback, that\n        callback is simply overwritten with this new callback.\n        \"\"\"\n        assert isinstance(data, bytes_type)\n        self._check_closed()\n        # We use bool(_write_buffer) as a proxy for write_buffer_size>0,\n        # so never put empty strings in the buffer.\n        if data:\n            # Break up large contiguous strings before inserting them in the\n            # write buffer, so we don't have to recopy the entire thing\n            # as we slice off pieces to send to the socket.\n            WRITE_BUFFER_CHUNK_SIZE = 128 * 1024\n            for i in range(0, len(data), WRITE_BUFFER_CHUNK_SIZE):\n                self._write_buffer.append(data[i:i + WRITE_BUFFER_CHUNK_SIZE])\n        if callback is not None:\n            self._write_callback = stack_context.wrap(callback)\n            future = None\n        else:\n            future = self._write_future = TracebackFuture()\n        if not self._connecting:\n            self._handle_write()\n            if self._write_buffer:\n                self._add_io_state(self.io_loop.WRITE)\n            self._maybe_add_error_listener()\n        return future\n\n    def set_close_callback(self, callback):\n        \"\"\"Call the given callback when the stream is closed.\"\"\"\n        self._close_callback = stack_context.wrap(callback)\n\n    def close(self, exc_info=False):\n        \"\"\"Close this stream.\n\n        If ``exc_info`` is true, set the ``error`` attribute to the current\n        exception from `sys.exc_info` (or if ``exc_info`` is a tuple,\n        use that instead of `sys.exc_info`).\n        \"\"\"\n        if not self.closed():\n            if exc_info:\n                if not isinstance(exc_info, tuple):\n                    exc_info = sys.exc_info()\n                if any(exc_info):\n                    self.error = exc_info[1]\n            if self._read_until_close:\n                if (self._streaming_callback is not None and\n                        self._read_buffer_size):\n                    self._run_callback(self._streaming_callback,\n                                       self._consume(self._read_buffer_size))\n                self._read_until_close = False\n                self._run_read_callback(self._consume(self._read_buffer_size))\n            if self._state is not None:\n                self.io_loop.remove_handler(self.fileno())\n                self._state = None\n            self.close_fd()\n            self._closed = True\n        self._maybe_run_close_callback()\n\n    def _maybe_run_close_callback(self):\n        # If there are pending callbacks, don't run the close callback\n        # until they're done (see _maybe_add_error_handler)\n        if self.closed() and self._pending_callbacks == 0:\n            futures = []\n            if self._read_future is not None:\n                futures.append(self._read_future)\n                self._read_future = None\n            if self._write_future is not None:\n                futures.append(self._write_future)\n                self._write_future = None\n            if self._connect_future is not None:\n                futures.append(self._connect_future)\n                self._connect_future = None\n            for future in futures:\n                future.set_exception(StreamClosedError())\n            if self._close_callback is not None:\n                cb = self._close_callback\n                self._close_callback = None\n                self._run_callback(cb)\n            # Delete any unfinished callbacks to break up reference cycles.\n            self._read_callback = self._write_callback = None\n            # Clear the buffers so they can be cleared immediately even\n            # if the IOStream object is kept alive by a reference cycle.\n            # TODO: Clear the read buffer too; it currently breaks some tests.\n            self._write_buffer = None\n\n    def reading(self):\n        \"\"\"Returns true if we are currently reading from the stream.\"\"\"\n        return self._read_callback is not None\n\n    def writing(self):\n        \"\"\"Returns true if we are currently writing to the stream.\"\"\"\n        return bool(self._write_buffer)\n\n    def closed(self):\n        \"\"\"Returns true if the stream has been closed.\"\"\"\n        return self._closed\n\n    def set_nodelay(self, value):\n        \"\"\"Sets the no-delay flag for this stream.\n\n        By default, data written to TCP streams may be held for a time\n        to make the most efficient use of bandwidth (according to\n        Nagle's algorithm).  The no-delay flag requests that data be\n        written as soon as possible, even if doing so would consume\n        additional bandwidth.\n\n        This flag is currently defined only for TCP-based ``IOStreams``.\n\n        .. versionadded:: 3.1\n        \"\"\"\n        pass\n\n    def _handle_events(self, fd, events):\n        if self.closed():\n            gen_log.warning(\"Got events for closed stream %s\", fd)\n            return\n        try:\n            if events & self.io_loop.READ:\n                self._handle_read()\n            if self.closed():\n                return\n            if events & self.io_loop.WRITE:\n                if self._connecting:\n                    self._handle_connect()\n                self._handle_write()\n            if self.closed():\n                return\n            if events & self.io_loop.ERROR:\n                self.error = self.get_fd_error()\n                # We may have queued up a user callback in _handle_read or\n                # _handle_write, so don't close the IOStream until those\n                # callbacks have had a chance to run.\n                self.io_loop.add_callback(self.close)\n                return\n            state = self.io_loop.ERROR\n            if self.reading():\n                state |= self.io_loop.READ\n            if self.writing():\n                state |= self.io_loop.WRITE\n            if state == self.io_loop.ERROR:\n                state |= self.io_loop.READ\n            if state != self._state:\n                assert self._state is not None, \\\n                    \"shouldn't happen: _handle_events without self._state\"\n                self._state = state\n                self.io_loop.update_handler(self.fileno(), self._state)\n        except Exception:\n            gen_log.error(\"Uncaught exception, closing connection.\",\n                          exc_info=True)\n            self.close(exc_info=True)\n            raise\n\n    def _run_callback(self, callback, *args):\n        def wrapper():\n            self._pending_callbacks -= 1\n            try:\n                callback(*args)\n            except Exception:\n                app_log.error(\"Uncaught exception, closing connection.\",\n                              exc_info=True)\n                # Close the socket on an uncaught exception from a user callback\n                # (It would eventually get closed when the socket object is\n                # gc'd, but we don't want to rely on gc happening before we\n                # run out of file descriptors)\n                self.close(exc_info=True)\n                # Re-raise the exception so that IOLoop.handle_callback_exception\n                # can see it and log the error\n                raise\n            self._maybe_add_error_listener()\n        # We schedule callbacks to be run on the next IOLoop iteration\n        # rather than running them directly for several reasons:\n        # * Prevents unbounded stack growth when a callback calls an\n        #   IOLoop operation that immediately runs another callback\n        # * Provides a predictable execution context for e.g.\n        #   non-reentrant mutexes\n        # * Ensures that the try/except in wrapper() is run outside\n        #   of the application's StackContexts\n        with stack_context.NullContext():\n            # stack_context was already captured in callback, we don't need to\n            # capture it again for IOStream's wrapper.  This is especially\n            # important if the callback was pre-wrapped before entry to\n            # IOStream (as in HTTPConnection._header_callback), as we could\n            # capture and leak the wrong context here.\n            self._pending_callbacks += 1\n            self.io_loop.add_callback(wrapper)\n\n    def _handle_read(self):\n        try:\n            try:\n                # Pretend to have a pending callback so that an EOF in\n                # _read_to_buffer doesn't trigger an immediate close\n                # callback.  At the end of this method we'll either\n                # estabilsh a real pending callback via\n                # _read_from_buffer or run the close callback.\n                #\n                # We need two try statements here so that\n                # pending_callbacks is decremented before the `except`\n                # clause below (which calls `close` and does need to\n                # trigger the callback)\n                self._pending_callbacks += 1\n                while not self.closed():\n                    # Read from the socket until we get EWOULDBLOCK or equivalent.\n                    # SSL sockets do some internal buffering, and if the data is\n                    # sitting in the SSL object's buffer select() and friends\n                    # can't see it; the only way to find out if it's there is to\n                    # try to read it.\n                    if self._read_to_buffer() == 0:\n                        break\n            finally:\n                self._pending_callbacks -= 1\n        except Exception:\n            gen_log.warning(\"error on read\", exc_info=True)\n            self.close(exc_info=True)\n            return\n        if self._read_from_buffer():\n            return\n        else:\n            self._maybe_run_close_callback()\n\n    def _set_read_callback(self, callback):\n        assert self._read_callback is None, \"Already reading\"\n        assert self._read_future is None, \"Already reading\"\n        if callback is not None:\n            self._read_callback = stack_context.wrap(callback)\n        else:\n            self._read_future = TracebackFuture()\n        return self._read_future\n\n    def _run_read_callback(self, data):\n        self._streaming_callback = None\n        if self._read_future is not None:\n            future = self._read_future\n            self._read_future = None\n            future.set_result(data)\n        if self._read_callback is not None:\n            callback = self._read_callback\n            self._read_callback = None\n            self._run_callback(callback, data)\n        else:\n            # If we scheduled a callback, we will add the error listener\n            # afterwards.  If we didn't, we have to do it now.\n            self._maybe_add_error_listener()\n\n    def _try_inline_read(self):\n        \"\"\"Attempt to complete the current read operation from buffered data.\n\n        If the read can be completed without blocking, schedules the\n        read callback on the next IOLoop iteration; otherwise starts\n        listening for reads on the socket.\n        \"\"\"\n        # See if we've already got the data from a previous read\n        if self._read_from_buffer():\n            return\n        self._check_closed()\n        try:\n            try:\n                # See comments in _handle_read about incrementing _pending_callbacks\n                self._pending_callbacks += 1\n                while not self.closed():\n                    if self._read_to_buffer() == 0:\n                        break\n            finally:\n                self._pending_callbacks -= 1\n        except Exception:\n            # If there was an in _read_to_buffer, we called close() already,\n            # but couldn't run the close callback because of _pending_callbacks.\n            # Before we escape from this function, run the close callback if\n            # applicable.\n            self._maybe_run_close_callback()\n            raise\n        if self._read_from_buffer():\n            return\n        self._maybe_add_error_listener()\n\n    def _read_to_buffer(self):\n        \"\"\"Reads from the socket and appends the result to the read buffer.\n\n        Returns the number of bytes read.  Returns 0 if there is nothing\n        to read (i.e. the read returns EWOULDBLOCK or equivalent).  On\n        error closes the socket and raises an exception.\n        \"\"\"\n        try:\n            chunk = self.read_from_fd()\n        except (socket.error, IOError, OSError) as e:\n            # ssl.SSLError is a subclass of socket.error\n            if e.args[0] in _ERRNO_CONNRESET:\n                # Treat ECONNRESET as a connection close rather than\n                # an error to minimize log spam  (the exception will\n                # be available on self.error for apps that care).\n                self.close(exc_info=True)\n                return\n            self.close(exc_info=True)\n            raise\n        if chunk is None:\n            return 0\n        self._read_buffer.append(chunk)\n        self._read_buffer_size += len(chunk)\n        if self._read_buffer_size >= self.max_buffer_size:\n            gen_log.error(\"Reached maximum read buffer size\")\n            self.close()\n            raise IOError(\"Reached maximum read buffer size\")\n        return len(chunk)\n\n    def _read_from_buffer(self):\n        \"\"\"Attempts to complete the currently-pending read from the buffer.\n\n        Returns True if the read was completed.\n        \"\"\"\n        if self._streaming_callback is not None and self._read_buffer_size:\n            bytes_to_consume = self._read_buffer_size\n            if self._read_bytes is not None:\n                bytes_to_consume = min(self._read_bytes, bytes_to_consume)\n                self._read_bytes -= bytes_to_consume\n            self._run_callback(self._streaming_callback,\n                               self._consume(bytes_to_consume))\n        if self._read_bytes is not None and self._read_buffer_size >= self._read_bytes:\n            num_bytes = self._read_bytes\n            self._read_bytes = None\n            self._run_read_callback(self._consume(num_bytes))\n            return True\n        elif self._read_delimiter is not None:\n            # Multi-byte delimiters (e.g. '\\r\\n') may straddle two\n            # chunks in the read buffer, so we can't easily find them\n            # without collapsing the buffer.  However, since protocols\n            # using delimited reads (as opposed to reads of a known\n            # length) tend to be \"line\" oriented, the delimiter is likely\n            # to be in the first few chunks.  Merge the buffer gradually\n            # since large merges are relatively expensive and get undone in\n            # consume().\n            if self._read_buffer:\n                while True:\n                    loc = self._read_buffer[0].find(self._read_delimiter)\n                    if loc != -1:\n                        delimiter_len = len(self._read_delimiter)\n                        self._read_delimiter = None\n                        self._run_read_callback(\n                            self._consume(loc + delimiter_len))\n                        return True\n                    if len(self._read_buffer) == 1:\n                        break\n                    _double_prefix(self._read_buffer)\n        elif self._read_regex is not None:\n            if self._read_buffer:\n                while True:\n                    m = self._read_regex.search(self._read_buffer[0])\n                    if m is not None:\n                        self._read_regex = None\n                        self._run_read_callback(self._consume(m.end()))\n                        return True\n                    if len(self._read_buffer) == 1:\n                        break\n                    _double_prefix(self._read_buffer)\n        return False\n\n    def _handle_write(self):\n        while self._write_buffer:\n            try:\n                if not self._write_buffer_frozen:\n                    # On windows, socket.send blows up if given a\n                    # write buffer that's too large, instead of just\n                    # returning the number of bytes it was able to\n                    # process.  Therefore we must not call socket.send\n                    # with more than 128KB at a time.\n                    _merge_prefix(self._write_buffer, 128 * 1024)\n                num_bytes = self.write_to_fd(self._write_buffer[0])\n                if num_bytes == 0:\n                    # With OpenSSL, if we couldn't write the entire buffer,\n                    # the very same string object must be used on the\n                    # next call to send.  Therefore we suppress\n                    # merging the write buffer after an incomplete send.\n                    # A cleaner solution would be to set\n                    # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, but this is\n                    # not yet accessible from python\n                    # (http://bugs.python.org/issue8240)\n                    self._write_buffer_frozen = True\n                    break\n                self._write_buffer_frozen = False\n                _merge_prefix(self._write_buffer, num_bytes)\n                self._write_buffer.popleft()\n            except (socket.error, IOError, OSError) as e:\n                if e.args[0] in _ERRNO_WOULDBLOCK:\n                    self._write_buffer_frozen = True\n                    break\n                else:\n                    if e.args[0] not in _ERRNO_CONNRESET:\n                        # Broken pipe errors are usually caused by connection\n                        # reset, and its better to not log EPIPE errors to\n                        # minimize log spam\n                        gen_log.warning(\"Write error on %s: %s\",\n                                        self.fileno(), e)\n                    self.close(exc_info=True)\n                    return\n        if not self._write_buffer:\n            if self._write_callback:\n                callback = self._write_callback\n                self._write_callback = None\n                self._run_callback(callback)\n            if self._write_future:\n                future = self._write_future\n                self._write_future = None\n                future.set_result(None)\n\n    def _consume(self, loc):\n        if loc == 0:\n            return b\"\"\n        _merge_prefix(self._read_buffer, loc)\n        self._read_buffer_size -= loc\n        return self._read_buffer.popleft()\n\n    def _check_closed(self):\n        if self.closed():\n            raise StreamClosedError(\"Stream is closed\")\n\n    def _maybe_add_error_listener(self):\n        if self._state is None and self._pending_callbacks == 0:\n            if self.closed():\n                self._maybe_run_close_callback()\n            else:\n                self._add_io_state(ioloop.IOLoop.READ)\n\n    def _add_io_state(self, state):\n        \"\"\"Adds `state` (IOLoop.{READ,WRITE} flags) to our event handler.\n\n        Implementation notes: Reads and writes have a fast path and a\n        slow path.  The fast path reads synchronously from socket\n        buffers, while the slow path uses `_add_io_state` to schedule\n        an IOLoop callback.  Note that in both cases, the callback is\n        run asynchronously with `_run_callback`.\n\n        To detect closed connections, we must have called\n        `_add_io_state` at some point, but we want to delay this as\n        much as possible so we don't have to set an `IOLoop.ERROR`\n        listener that will be overwritten by the next slow-path\n        operation.  As long as there are callbacks scheduled for\n        fast-path ops, those callbacks may do more reads.\n        If a sequence of fast-path ops do not end in a slow-path op,\n        (e.g. for an @asynchronous long-poll request), we must add\n        the error handler.  This is done in `_run_callback` and `write`\n        (since the write callback is optional so we can have a\n        fast-path write with no `_run_callback`)\n        \"\"\"\n        if self.closed():\n            # connection has been closed, so there can be no future events\n            return\n        if self._state is None:\n            self._state = ioloop.IOLoop.ERROR | state\n            with stack_context.NullContext():\n                self.io_loop.add_handler(\n                    self.fileno(), self._handle_events, self._state)\n        elif not self._state & state:\n            self._state = self._state | state\n            self.io_loop.update_handler(self.fileno(), self._state)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 70,
                            "end_lineno": 665,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        },
        {
            "old_file_content": "from __future__ import absolute_import, division, print_function, with_statement\nfrom tornado import netutil\nfrom tornado.ioloop import IOLoop\nfrom tornado.iostream import IOStream, SSLIOStream, PipeIOStream, StreamClosedError\nfrom tornado.httputil import HTTPHeaders\nfrom tornado.log import gen_log, app_log\nfrom tornado.netutil import ssl_wrap_socket\nfrom tornado.stack_context import NullContext\nfrom tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, bind_unused_port, ExpectLog, gen_test\nfrom tornado.test.util import unittest, skipIfNonUnix\nfrom tornado.web import RequestHandler, Application\nimport errno\nimport logging\nimport os\nimport platform\nimport socket\nimport ssl\nimport sys\n\n\nclass HelloHandler(RequestHandler):\n    def get(self):\n        self.write(\"Hello\")\n\n\nclass TestIOStreamWebMixin(object):\n    def _make_client_iostream(self):\n        raise NotImplementedError()\n\n    def get_app(self):\n        return Application([('/', HelloHandler)])\n\n    def test_connection_closed(self):\n        # When a server sends a response and then closes the connection,\n        # the client must be allowed to read the data before the IOStream\n        # closes itself.  Epoll reports closed connections with a separate\n        # EPOLLRDHUP event delivered at the same time as the read event,\n        # while kqueue reports them as a second read/write event with an EOF\n        # flag.\n        response = self.fetch(\"/\", headers={\"Connection\": \"close\"})\n        response.rethrow()\n\n    def test_read_until_close(self):\n        stream = self._make_client_iostream()\n        stream.connect(('localhost', self.get_http_port()), callback=self.stop)\n        self.wait()\n        stream.write(b\"GET / HTTP/1.0\\r\\n\\r\\n\")\n\n        stream.read_until_close(self.stop)\n        data = self.wait()\n        self.assertTrue(data.startswith(b\"HTTP/1.0 200\"))\n        self.assertTrue(data.endswith(b\"Hello\"))\n\n    def test_read_zero_bytes(self):\n        self.stream = self._make_client_iostream()\n        self.stream.connect((\"localhost\", self.get_http_port()),\n                            callback=self.stop)\n        self.wait()\n        self.stream.write(b\"GET / HTTP/1.0\\r\\n\\r\\n\")\n\n        # normal read\n        self.stream.read_bytes(9, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"HTTP/1.0 \")\n\n        # zero bytes\n        self.stream.read_bytes(0, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"\")\n\n        # another normal read\n        self.stream.read_bytes(3, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"200\")\n\n        self.stream.close()\n\n    def test_write_while_connecting(self):\n        stream = self._make_client_iostream()\n        connected = [False]\n\n        def connected_callback():\n            connected[0] = True\n            self.stop()\n        stream.connect((\"localhost\", self.get_http_port()),\n                       callback=connected_callback)\n        # unlike the previous tests, try to write before the connection\n        # is complete.\n        written = [False]\n\n        def write_callback():\n            written[0] = True\n            self.stop()\n        stream.write(b\"GET / HTTP/1.0\\r\\nConnection: close\\r\\n\\r\\n\",\n                     callback=write_callback)\n        self.assertTrue(not connected[0])\n        # by the time the write has flushed, the connection callback has\n        # also run\n        try:\n            self.wait(lambda: connected[0] and written[0])\n        finally:\n            logging.debug((connected, written))\n\n        stream.read_until_close(self.stop)\n        data = self.wait()\n        self.assertTrue(data.endswith(b\"Hello\"))\n\n        stream.close()\n\n    @gen_test\n    def test_future_interface(self):\n        \"\"\"Basic test of IOStream's ability to return Futures.\"\"\"\n        stream = self._make_client_iostream()\n        yield stream.connect((\"localhost\", self.get_http_port()))\n        yield stream.write(b\"GET / HTTP/1.0\\r\\n\\r\\n\")\n        first_line = yield stream.read_until(b\"\\r\\n\")\n        self.assertEqual(first_line, b\"HTTP/1.0 200 OK\\r\\n\")\n        # callback=None is equivalent to no callback.\n        header_data = yield stream.read_until(b\"\\r\\n\\r\\n\", callback=None)\n        headers = HTTPHeaders.parse(header_data.decode('latin1'))\n        content_length = int(headers['Content-Length'])\n        body = yield stream.read_bytes(content_length)\n        self.assertEqual(body, b'Hello')\n        stream.close()\n\n    @gen_test\n    def test_future_close_while_reading(self):\n        stream = self._make_client_iostream()\n        yield stream.connect((\"localhost\", self.get_http_port()))\n        yield stream.write(b\"GET / HTTP/1.0\\r\\n\\r\\n\")\n        with self.assertRaises(StreamClosedError):\n            yield stream.read_bytes(1024 * 1024)\n        stream.close()\n\n    @gen_test\n    def test_future_read_until_close(self):\n        # Ensure that the data comes through before the StreamClosedError.\n        stream = self._make_client_iostream()\n        yield stream.connect((\"localhost\", self.get_http_port()))\n        yield stream.write(b\"GET / HTTP/1.0\\r\\nConnection: close\\r\\n\\r\\n\")\n        yield stream.read_until(b\"\\r\\n\\r\\n\")\n        body = yield stream.read_until_close()\n        self.assertEqual(body, b\"Hello\")\n\n        # Nothing else to read; the error comes immediately without waiting\n        # for yield.\n        with self.assertRaises(StreamClosedError):\n            stream.read_bytes(1)\n\n\nclass TestIOStreamMixin(object):\n    def _make_server_iostream(self, connection, **kwargs):\n        raise NotImplementedError()\n\n    def _make_client_iostream(self, connection, **kwargs):\n        raise NotImplementedError()\n\n    def make_iostream_pair(self, **kwargs):\n        listener, port = bind_unused_port()\n        streams = [None, None]\n\n        def accept_callback(connection, address):\n            streams[0] = self._make_server_iostream(connection, **kwargs)\n            self.stop()\n\n        def connect_callback():\n            streams[1] = client_stream\n            self.stop()\n        netutil.add_accept_handler(listener, accept_callback,\n                                   io_loop=self.io_loop)\n        client_stream = self._make_client_iostream(socket.socket(), **kwargs)\n        client_stream.connect(('127.0.0.1', port),\n                              callback=connect_callback)\n        self.wait(condition=lambda: all(streams))\n        self.io_loop.remove_handler(listener.fileno())\n        listener.close()\n        return streams\n\n    def test_streaming_callback_with_data_in_buffer(self):\n        server, client = self.make_iostream_pair()\n        client.write(b\"abcd\\r\\nefgh\")\n        server.read_until(b\"\\r\\n\", self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"abcd\\r\\n\")\n\n        def closed_callback(chunk):\n            self.fail()\n        server.read_until_close(callback=closed_callback,\n                                streaming_callback=self.stop)\n        # self.io_loop.add_timeout(self.io_loop.time() + 0.01, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"efgh\")\n        server.close()\n        client.close()\n\n    def test_write_zero_bytes(self):\n        # Attempting to write zero bytes should run the callback without\n        # going into an infinite loop.\n        server, client = self.make_iostream_pair()\n        server.write(b'', callback=self.stop)\n        self.wait()\n        # As a side effect, the stream is now listening for connection\n        # close (if it wasn't already), but is not listening for writes\n        self.assertEqual(server._state, IOLoop.READ | IOLoop.ERROR)\n        server.close()\n        client.close()\n\n    def test_connection_refused(self):\n        # When a connection is refused, the connect callback should not\n        # be run.  (The kqueue IOLoop used to behave differently from the\n        # epoll IOLoop in this respect)\n        server_socket, port = bind_unused_port()\n        server_socket.close()\n        stream = IOStream(socket.socket(), self.io_loop)\n        self.connect_called = False\n\n        def connect_callback():\n            self.connect_called = True\n        stream.set_close_callback(self.stop)\n        # log messages vary by platform and ioloop implementation\n        with ExpectLog(gen_log, \".*\", required=False):\n            stream.connect((\"localhost\", port), connect_callback)\n            self.wait()\n        self.assertFalse(self.connect_called)\n        self.assertTrue(isinstance(stream.error, socket.error), stream.error)\n        if sys.platform != 'cygwin':\n            # cygwin's errnos don't match those used on native windows python\n            self.assertEqual(stream.error.args[0], errno.ECONNREFUSED)\n\n    def test_gaierror(self):\n        # Test that IOStream sets its exc_info on getaddrinfo error\n        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)\n        stream = IOStream(s, io_loop=self.io_loop)\n        stream.set_close_callback(self.stop)\n        # To reliably generate a gaierror we use a malformed domain name\n        # instead of a name that's simply unlikely to exist (since\n        # opendns and some ISPs return bogus addresses for nonexistent\n        # domains instead of the proper error codes).\n        with ExpectLog(gen_log, \"Connect error\"):\n            stream.connect(('an invalid domain', 54321))\n            self.assertTrue(isinstance(stream.error, socket.gaierror), stream.error)\n\n    def test_read_callback_error(self):\n        # Test that IOStream sets its exc_info when a read callback throws\n        server, client = self.make_iostream_pair()\n        try:\n            server.set_close_callback(self.stop)\n            with ExpectLog(\n                app_log, \"(Uncaught exception|Exception in callback)\"\n            ):\n                # Clear ExceptionStackContext so IOStream catches error\n                with NullContext():\n                    server.read_bytes(1, callback=lambda data: 1 / 0)\n                client.write(b\"1\")\n                self.wait()\n            self.assertTrue(isinstance(server.error, ZeroDivisionError))\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_callback(self):\n        server, client = self.make_iostream_pair()\n        try:\n            chunks = []\n            final_called = []\n\n            def streaming_callback(data):\n                chunks.append(data)\n                self.stop()\n\n            def final_callback(data):\n                self.assertFalse(data)\n                final_called.append(True)\n                self.stop()\n            server.read_bytes(6, callback=final_callback,\n                              streaming_callback=streaming_callback)\n            client.write(b\"1234\")\n            self.wait(condition=lambda: chunks)\n            client.write(b\"5678\")\n            self.wait(condition=lambda: final_called)\n            self.assertEqual(chunks, [b\"1234\", b\"56\"])\n\n            # the rest of the last chunk is still in the buffer\n            server.read_bytes(2, callback=self.stop)\n            data = self.wait()\n            self.assertEqual(data, b\"78\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_until_close(self):\n        server, client = self.make_iostream_pair()\n        try:\n            chunks = []\n            closed = [False]\n\n            def streaming_callback(data):\n                chunks.append(data)\n                self.stop()\n            def close_callback(data):\n                assert not data, data\n                closed[0] = True\n                self.stop()\n            client.read_until_close(callback=close_callback,\n                                    streaming_callback=streaming_callback)\n            server.write(b\"1234\")\n            self.wait(condition=lambda: len(chunks) == 1)\n            server.write(b\"5678\", self.stop)\n            self.wait()\n            server.close()\n            self.wait(condition=lambda: closed[0])\n            self.assertEqual(chunks, [b\"1234\", b\"5678\"])\n        finally:\n            server.close()\n            client.close()\n\n    def test_delayed_close_callback(self):\n        # The scenario:  Server closes the connection while there is a pending\n        # read that can be served out of buffered data.  The client does not\n        # run the close_callback as soon as it detects the close, but rather\n        # defers it until after the buffered read has finished.\n        server, client = self.make_iostream_pair()\n        try:\n            client.set_close_callback(self.stop)\n            server.write(b\"12\")\n            chunks = []\n\n            def callback1(data):\n                chunks.append(data)\n                client.read_bytes(1, callback2)\n                server.close()\n\n            def callback2(data):\n                chunks.append(data)\n            client.read_bytes(1, callback1)\n            self.wait()  # stopped by close_callback\n            self.assertEqual(chunks, [b\"1\", b\"2\"])\n        finally:\n            server.close()\n            client.close()\n\n    def test_future_delayed_close_callback(self):\n        # Same as test_delayed_close_callback, but with the future interface.\n        server, client = self.make_iostream_pair()\n        # We can't call make_iostream_pair inside a gen_test function\n        # because the ioloop is not reentrant.\n        @gen_test\n        def f(self):\n            server.write(b\"12\")\n            chunks = []\n            chunks.append((yield client.read_bytes(1)))\n            server.close()\n            chunks.append((yield client.read_bytes(1)))\n            self.assertEqual(chunks, [b\"1\", b\"2\"])\n        try:\n            f(self)\n        finally:\n            server.close()\n            client.close()\n\n    def test_close_buffered_data(self):\n        # Similar to the previous test, but with data stored in the OS's\n        # socket buffers instead of the IOStream's read buffer.  Out-of-band\n        # close notifications must be delayed until all data has been\n        # drained into the IOStream buffer. (epoll used to use out-of-band\n        # close events with EPOLLRDHUP, but no longer)\n        #\n        # This depends on the read_chunk_size being smaller than the\n        # OS socket buffer, so make it small.\n        server, client = self.make_iostream_pair(read_chunk_size=256)\n        try:\n            server.write(b\"A\" * 512)\n            client.read_bytes(256, self.stop)\n            data = self.wait()\n            self.assertEqual(b\"A\" * 256, data)\n            server.close()\n            # Allow the close to propagate to the client side of the\n            # connection.  Using add_callback instead of add_timeout\n            # doesn't seem to work, even with multiple iterations\n            self.io_loop.add_timeout(self.io_loop.time() + 0.01, self.stop)\n            self.wait()\n            client.read_bytes(256, self.stop)\n            data = self.wait()\n            self.assertEqual(b\"A\" * 256, data)\n        finally:\n            server.close()\n            client.close()\n\n    def test_read_until_close_after_close(self):\n        # Similar to test_delayed_close_callback, but read_until_close takes\n        # a separate code path so test it separately.\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(b\"1234\")\n            server.close()\n            self.wait()\n            client.read_until_close(self.stop)\n            data = self.wait()\n            self.assertEqual(data, b\"1234\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_read_until_close_after_close(self):\n        # Same as the preceding test but with a streaming_callback.\n        # All data should go through the streaming callback,\n        # and the final read callback just gets an empty string.\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(b\"1234\")\n            server.close()\n            self.wait()\n            streaming_data = []\n            client.read_until_close(self.stop,\n                                    streaming_callback=streaming_data.append)\n            data = self.wait()\n            self.assertEqual(b'', data)\n            self.assertEqual(b''.join(streaming_data), b\"1234\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_large_read_until(self):\n        # Performance test: read_until used to have a quadratic component\n        # so a read_until of 4MB would take 8 seconds; now it takes 0.25\n        # seconds.\n        server, client = self.make_iostream_pair()\n        try:\n            # This test fails on pypy with ssl.  I think it's because\n            # pypy's gc defeats moves objects, breaking the\n            # \"frozen write buffer\" assumption.\n            if (isinstance(server, SSLIOStream) and\n                    platform.python_implementation() == 'PyPy'):\n                raise unittest.SkipTest(\n                    \"pypy gc causes problems with openssl\")\n            NUM_KB = 4096\n            for i in range(NUM_KB):\n                client.write(b\"A\" * 1024)\n            client.write(b\"\\r\\n\")\n            server.read_until(b\"\\r\\n\", self.stop)\n            data = self.wait()\n            self.assertEqual(len(data), NUM_KB * 1024 + 2)\n        finally:\n            server.close()\n            client.close()\n\n    def test_close_callback_with_pending_read(self):\n        # Regression test for a bug that was introduced in 2.3\n        # where the IOStream._close_callback would never be called\n        # if there were pending reads.\n        OK = b\"OK\\r\\n\"\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(OK)\n            client.read_until(b\"\\r\\n\", self.stop)\n            res = self.wait()\n            self.assertEqual(res, OK)\n\n            server.close()\n            client.read_until(b\"\\r\\n\", lambda x: x)\n            # If _close_callback (self.stop) is not called,\n            # an AssertionError: Async operation timed out after 5 seconds\n            # will be raised.\n            res = self.wait()\n            self.assertTrue(res is None)\n        finally:\n            server.close()\n            client.close()\n\n    @skipIfNonUnix\n    def test_inline_read_error(self):\n        # An error on an inline read is raised without logging (on the\n        # assumption that it will eventually be noticed or logged further\n        # up the stack).\n        #\n        # This test is posix-only because windows os.close() doesn't work\n        # on socket FDs, but we can't close the socket object normally\n        # because we won't get the error we want if the socket knows\n        # it's closed.\n        server, client = self.make_iostream_pair()\n        try:\n            os.close(server.socket.fileno())\n            with self.assertRaises(socket.error):\n                server.read_bytes(1, lambda data: None)\n        finally:\n            server.close()\n            client.close()\n\n    def test_async_read_error_logging(self):\n        # Socket errors on asynchronous reads should be logged (but only\n        # once).\n        server, client = self.make_iostream_pair()\n        server.set_close_callback(self.stop)\n        try:\n            # Start a read that will be fullfilled asynchronously.\n            server.read_bytes(1, lambda data: None)\n            client.write(b'a')\n            # Stub out read_from_fd to make it fail.\n\n            def fake_read_from_fd():\n                os.close(server.socket.fileno())\n                server.__class__.read_from_fd(server)\n            server.read_from_fd = fake_read_from_fd\n            # This log message is from _handle_read (not read_from_fd).\n            with ExpectLog(gen_log, \"error on read\"):\n                self.wait()\n        finally:\n            server.close()\n            client.close()\n\n\nclass TestIOStreamWebHTTP(TestIOStreamWebMixin, AsyncHTTPTestCase):\n    def _make_client_iostream(self):\n        return IOStream(socket.socket(), io_loop=self.io_loop)\n\n\nclass TestIOStreamWebHTTPS(TestIOStreamWebMixin, AsyncHTTPSTestCase):\n    def _make_client_iostream(self):\n        return SSLIOStream(socket.socket(), io_loop=self.io_loop)\n\n\nclass TestIOStream(TestIOStreamMixin, AsyncTestCase):\n    def _make_server_iostream(self, connection, **kwargs):\n        return IOStream(connection, **kwargs)\n\n    def _make_client_iostream(self, connection, **kwargs):\n        return IOStream(connection, **kwargs)\n\n\nclass TestIOStreamSSL(TestIOStreamMixin, AsyncTestCase):\n    def _make_server_iostream(self, connection, **kwargs):\n        ssl_options = dict(\n            certfile=os.path.join(os.path.dirname(__file__), 'test.crt'),\n            keyfile=os.path.join(os.path.dirname(__file__), 'test.key'),\n        )\n        connection = ssl.wrap_socket(connection,\n                                     server_side=True,\n                                     do_handshake_on_connect=False,\n                                     **ssl_options)\n        return SSLIOStream(connection, io_loop=self.io_loop, **kwargs)\n\n    def _make_client_iostream(self, connection, **kwargs):\n        return SSLIOStream(connection, io_loop=self.io_loop, **kwargs)\n\n\n# This will run some tests that are basically redundant but it's the\n# simplest way to make sure that it works to pass an SSLContext\n# instead of an ssl_options dict to the SSLIOStream constructor.\n@unittest.skipIf(not hasattr(ssl, 'SSLContext'), 'ssl.SSLContext not present')\nclass TestIOStreamSSLContext(TestIOStreamMixin, AsyncTestCase):\n    def _make_server_iostream(self, connection, **kwargs):\n        context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)\n        context.load_cert_chain(\n            os.path.join(os.path.dirname(__file__), 'test.crt'),\n            os.path.join(os.path.dirname(__file__), 'test.key'))\n        connection = ssl_wrap_socket(connection, context,\n                                     server_side=True,\n                                     do_handshake_on_connect=False)\n        return SSLIOStream(connection, io_loop=self.io_loop, **kwargs)\n\n    def _make_client_iostream(self, connection, **kwargs):\n        context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)\n        return SSLIOStream(connection, io_loop=self.io_loop,\n                           ssl_options=context, **kwargs)\n\n\n@skipIfNonUnix\nclass TestPipeIOStream(AsyncTestCase):\n    def test_pipe_iostream(self):\n        r, w = os.pipe()\n\n        rs = PipeIOStream(r, io_loop=self.io_loop)\n        ws = PipeIOStream(w, io_loop=self.io_loop)\n\n        ws.write(b\"hel\")\n        ws.write(b\"lo world\")\n\n        rs.read_until(b' ', callback=self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"hello \")\n\n        rs.read_bytes(3, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"wor\")\n\n        ws.close()\n\n        rs.read_until_close(self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"ld\")\n\n        rs.close()\n\n    def test_pipe_iostream_big_write(self):\n        r, w = os.pipe()\n\n        rs = PipeIOStream(r, io_loop=self.io_loop)\n        ws = PipeIOStream(w, io_loop=self.io_loop)\n\n        NUM_BYTES = 1048576\n\n        # Write 1MB of data, which should fill the buffer\n        ws.write(b\"1\" * NUM_BYTES)\n\n        rs.read_bytes(NUM_BYTES, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"1\" * NUM_BYTES)\n\n        ws.close()\n        rs.close()\n",
            "new_file_content": "from __future__ import absolute_import, division, print_function, with_statement\nfrom tornado import netutil\nfrom tornado.ioloop import IOLoop\nfrom tornado.iostream import IOStream, SSLIOStream, PipeIOStream, StreamClosedError\nfrom tornado.httputil import HTTPHeaders\nfrom tornado.log import gen_log, app_log\nfrom tornado.netutil import ssl_wrap_socket\nfrom tornado.stack_context import NullContext\nfrom tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, bind_unused_port, ExpectLog, gen_test\nfrom tornado.test.util import unittest, skipIfNonUnix\nfrom tornado.web import RequestHandler, Application\nimport errno\nimport logging\nimport os\nimport platform\nimport socket\nimport ssl\nimport sys\n\n\nclass HelloHandler(RequestHandler):\n    def get(self):\n        self.write(\"Hello\")\n\n\nclass TestIOStreamWebMixin(object):\n    def _make_client_iostream(self):\n        raise NotImplementedError()\n\n    def get_app(self):\n        return Application([('/', HelloHandler)])\n\n    def test_connection_closed(self):\n        # When a server sends a response and then closes the connection,\n        # the client must be allowed to read the data before the IOStream\n        # closes itself.  Epoll reports closed connections with a separate\n        # EPOLLRDHUP event delivered at the same time as the read event,\n        # while kqueue reports them as a second read/write event with an EOF\n        # flag.\n        response = self.fetch(\"/\", headers={\"Connection\": \"close\"})\n        response.rethrow()\n\n    def test_read_until_close(self):\n        stream = self._make_client_iostream()\n        stream.connect(('localhost', self.get_http_port()), callback=self.stop)\n        self.wait()\n        stream.write(b\"GET / HTTP/1.0\\r\\n\\r\\n\")\n\n        stream.read_until_close(self.stop)\n        data = self.wait()\n        self.assertTrue(data.startswith(b\"HTTP/1.0 200\"))\n        self.assertTrue(data.endswith(b\"Hello\"))\n\n    def test_read_zero_bytes(self):\n        self.stream = self._make_client_iostream()\n        self.stream.connect((\"localhost\", self.get_http_port()),\n                            callback=self.stop)\n        self.wait()\n        self.stream.write(b\"GET / HTTP/1.0\\r\\n\\r\\n\")\n\n        # normal read\n        self.stream.read_bytes(9, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"HTTP/1.0 \")\n\n        # zero bytes\n        self.stream.read_bytes(0, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"\")\n\n        # another normal read\n        self.stream.read_bytes(3, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"200\")\n\n        self.stream.close()\n\n    def test_write_while_connecting(self):\n        stream = self._make_client_iostream()\n        connected = [False]\n\n        def connected_callback():\n            connected[0] = True\n            self.stop()\n        stream.connect((\"localhost\", self.get_http_port()),\n                       callback=connected_callback)\n        # unlike the previous tests, try to write before the connection\n        # is complete.\n        written = [False]\n\n        def write_callback():\n            written[0] = True\n            self.stop()\n        stream.write(b\"GET / HTTP/1.0\\r\\nConnection: close\\r\\n\\r\\n\",\n                     callback=write_callback)\n        self.assertTrue(not connected[0])\n        # by the time the write has flushed, the connection callback has\n        # also run\n        try:\n            self.wait(lambda: connected[0] and written[0])\n        finally:\n            logging.debug((connected, written))\n\n        stream.read_until_close(self.stop)\n        data = self.wait()\n        self.assertTrue(data.endswith(b\"Hello\"))\n\n        stream.close()\n\n    @gen_test\n    def test_future_interface(self):\n        \"\"\"Basic test of IOStream's ability to return Futures.\"\"\"\n        stream = self._make_client_iostream()\n        yield stream.connect((\"localhost\", self.get_http_port()))\n        yield stream.write(b\"GET / HTTP/1.0\\r\\n\\r\\n\")\n        first_line = yield stream.read_until(b\"\\r\\n\")\n        self.assertEqual(first_line, b\"HTTP/1.0 200 OK\\r\\n\")\n        # callback=None is equivalent to no callback.\n        header_data = yield stream.read_until(b\"\\r\\n\\r\\n\", callback=None)\n        headers = HTTPHeaders.parse(header_data.decode('latin1'))\n        content_length = int(headers['Content-Length'])\n        body = yield stream.read_bytes(content_length)\n        self.assertEqual(body, b'Hello')\n        stream.close()\n\n    @gen_test\n    def test_future_close_while_reading(self):\n        stream = self._make_client_iostream()\n        yield stream.connect((\"localhost\", self.get_http_port()))\n        yield stream.write(b\"GET / HTTP/1.0\\r\\n\\r\\n\")\n        with self.assertRaises(StreamClosedError):\n            yield stream.read_bytes(1024 * 1024)\n        stream.close()\n\n    @gen_test\n    def test_future_read_until_close(self):\n        # Ensure that the data comes through before the StreamClosedError.\n        stream = self._make_client_iostream()\n        yield stream.connect((\"localhost\", self.get_http_port()))\n        yield stream.write(b\"GET / HTTP/1.0\\r\\nConnection: close\\r\\n\\r\\n\")\n        yield stream.read_until(b\"\\r\\n\\r\\n\")\n        body = yield stream.read_until_close()\n        self.assertEqual(body, b\"Hello\")\n\n        # Nothing else to read; the error comes immediately without waiting\n        # for yield.\n        with self.assertRaises(StreamClosedError):\n            stream.read_bytes(1)\n\n\nclass TestIOStreamMixin(object):\n    def _make_server_iostream(self, connection, **kwargs):\n        raise NotImplementedError()\n\n    def _make_client_iostream(self, connection, **kwargs):\n        raise NotImplementedError()\n\n    def make_iostream_pair(self, **kwargs):\n        listener, port = bind_unused_port()\n        streams = [None, None]\n\n        def accept_callback(connection, address):\n            streams[0] = self._make_server_iostream(connection, **kwargs)\n            self.stop()\n\n        def connect_callback():\n            streams[1] = client_stream\n            self.stop()\n        netutil.add_accept_handler(listener, accept_callback,\n                                   io_loop=self.io_loop)\n        client_stream = self._make_client_iostream(socket.socket(), **kwargs)\n        client_stream.connect(('127.0.0.1', port),\n                              callback=connect_callback)\n        self.wait(condition=lambda: all(streams))\n        self.io_loop.remove_handler(listener.fileno())\n        listener.close()\n        return streams\n\n    def test_streaming_callback_with_data_in_buffer(self):\n        server, client = self.make_iostream_pair()\n        client.write(b\"abcd\\r\\nefgh\")\n        server.read_until(b\"\\r\\n\", self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"abcd\\r\\n\")\n\n        def closed_callback(chunk):\n            self.fail()\n        server.read_until_close(callback=closed_callback,\n                                streaming_callback=self.stop)\n        # self.io_loop.add_timeout(self.io_loop.time() + 0.01, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"efgh\")\n        server.close()\n        client.close()\n\n    def test_write_zero_bytes(self):\n        # Attempting to write zero bytes should run the callback without\n        # going into an infinite loop.\n        server, client = self.make_iostream_pair()\n        server.write(b'', callback=self.stop)\n        self.wait()\n        # As a side effect, the stream is now listening for connection\n        # close (if it wasn't already), but is not listening for writes\n        self.assertEqual(server._state, IOLoop.READ | IOLoop.ERROR)\n        server.close()\n        client.close()\n\n    def test_connection_refused(self):\n        # When a connection is refused, the connect callback should not\n        # be run.  (The kqueue IOLoop used to behave differently from the\n        # epoll IOLoop in this respect)\n        server_socket, port = bind_unused_port()\n        server_socket.close()\n        stream = IOStream(socket.socket(), self.io_loop)\n        self.connect_called = False\n\n        def connect_callback():\n            self.connect_called = True\n        stream.set_close_callback(self.stop)\n        # log messages vary by platform and ioloop implementation\n        with ExpectLog(gen_log, \".*\", required=False):\n            stream.connect((\"localhost\", port), connect_callback)\n            self.wait()\n        self.assertFalse(self.connect_called)\n        self.assertTrue(isinstance(stream.error, socket.error), stream.error)\n        if sys.platform != 'cygwin':\n            # cygwin's errnos don't match those used on native windows python\n            self.assertEqual(stream.error.args[0], errno.ECONNREFUSED)\n\n    def test_gaierror(self):\n        # Test that IOStream sets its exc_info on getaddrinfo error\n        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)\n        stream = IOStream(s, io_loop=self.io_loop)\n        stream.set_close_callback(self.stop)\n        # To reliably generate a gaierror we use a malformed domain name\n        # instead of a name that's simply unlikely to exist (since\n        # opendns and some ISPs return bogus addresses for nonexistent\n        # domains instead of the proper error codes).\n        with ExpectLog(gen_log, \"Connect error\"):\n            stream.connect(('an invalid domain', 54321))\n            self.assertTrue(isinstance(stream.error, socket.gaierror), stream.error)\n\n    def test_read_callback_error(self):\n        # Test that IOStream sets its exc_info when a read callback throws\n        server, client = self.make_iostream_pair()\n        try:\n            server.set_close_callback(self.stop)\n            with ExpectLog(\n                app_log, \"(Uncaught exception|Exception in callback)\"\n            ):\n                # Clear ExceptionStackContext so IOStream catches error\n                with NullContext():\n                    server.read_bytes(1, callback=lambda data: 1 / 0)\n                client.write(b\"1\")\n                self.wait()\n            self.assertTrue(isinstance(server.error, ZeroDivisionError))\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_callback(self):\n        server, client = self.make_iostream_pair()\n        try:\n            chunks = []\n            final_called = []\n\n            def streaming_callback(data):\n                chunks.append(data)\n                self.stop()\n\n            def final_callback(data):\n                self.assertFalse(data)\n                final_called.append(True)\n                self.stop()\n            server.read_bytes(6, callback=final_callback,\n                              streaming_callback=streaming_callback)\n            client.write(b\"1234\")\n            self.wait(condition=lambda: chunks)\n            client.write(b\"5678\")\n            self.wait(condition=lambda: final_called)\n            self.assertEqual(chunks, [b\"1234\", b\"56\"])\n\n            # the rest of the last chunk is still in the buffer\n            server.read_bytes(2, callback=self.stop)\n            data = self.wait()\n            self.assertEqual(data, b\"78\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_until_close(self):\n        server, client = self.make_iostream_pair()\n        try:\n            chunks = []\n            closed = [False]\n\n            def streaming_callback(data):\n                chunks.append(data)\n                self.stop()\n            def close_callback(data):\n                assert not data, data\n                closed[0] = True\n                self.stop()\n            client.read_until_close(callback=close_callback,\n                                    streaming_callback=streaming_callback)\n            server.write(b\"1234\")\n            self.wait(condition=lambda: len(chunks) == 1)\n            server.write(b\"5678\", self.stop)\n            self.wait()\n            server.close()\n            self.wait(condition=lambda: closed[0])\n            self.assertEqual(chunks, [b\"1234\", b\"5678\"])\n        finally:\n            server.close()\n            client.close()\n\n    def test_delayed_close_callback(self):\n        # The scenario:  Server closes the connection while there is a pending\n        # read that can be served out of buffered data.  The client does not\n        # run the close_callback as soon as it detects the close, but rather\n        # defers it until after the buffered read has finished.\n        server, client = self.make_iostream_pair()\n        try:\n            client.set_close_callback(self.stop)\n            server.write(b\"12\")\n            chunks = []\n\n            def callback1(data):\n                chunks.append(data)\n                client.read_bytes(1, callback2)\n                server.close()\n\n            def callback2(data):\n                chunks.append(data)\n            client.read_bytes(1, callback1)\n            self.wait()  # stopped by close_callback\n            self.assertEqual(chunks, [b\"1\", b\"2\"])\n        finally:\n            server.close()\n            client.close()\n\n    def test_future_delayed_close_callback(self):\n        # Same as test_delayed_close_callback, but with the future interface.\n        server, client = self.make_iostream_pair()\n        # We can't call make_iostream_pair inside a gen_test function\n        # because the ioloop is not reentrant.\n        @gen_test\n        def f(self):\n            server.write(b\"12\")\n            chunks = []\n            chunks.append((yield client.read_bytes(1)))\n            server.close()\n            chunks.append((yield client.read_bytes(1)))\n            self.assertEqual(chunks, [b\"1\", b\"2\"])\n        try:\n            f(self)\n        finally:\n            server.close()\n            client.close()\n\n    def test_close_buffered_data(self):\n        # Similar to the previous test, but with data stored in the OS's\n        # socket buffers instead of the IOStream's read buffer.  Out-of-band\n        # close notifications must be delayed until all data has been\n        # drained into the IOStream buffer. (epoll used to use out-of-band\n        # close events with EPOLLRDHUP, but no longer)\n        #\n        # This depends on the read_chunk_size being smaller than the\n        # OS socket buffer, so make it small.\n        server, client = self.make_iostream_pair(read_chunk_size=256)\n        try:\n            server.write(b\"A\" * 512)\n            client.read_bytes(256, self.stop)\n            data = self.wait()\n            self.assertEqual(b\"A\" * 256, data)\n            server.close()\n            # Allow the close to propagate to the client side of the\n            # connection.  Using add_callback instead of add_timeout\n            # doesn't seem to work, even with multiple iterations\n            self.io_loop.add_timeout(self.io_loop.time() + 0.01, self.stop)\n            self.wait()\n            client.read_bytes(256, self.stop)\n            data = self.wait()\n            self.assertEqual(b\"A\" * 256, data)\n        finally:\n            server.close()\n            client.close()\n\n    def test_read_until_close_after_close(self):\n        # Similar to test_delayed_close_callback, but read_until_close takes\n        # a separate code path so test it separately.\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(b\"1234\")\n            server.close()\n            self.wait()\n            client.read_until_close(self.stop)\n            data = self.wait()\n            self.assertEqual(data, b\"1234\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_read_until_close_after_close(self):\n        # Same as the preceding test but with a streaming_callback.\n        # All data should go through the streaming callback,\n        # and the final read callback just gets an empty string.\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(b\"1234\")\n            server.close()\n            self.wait()\n            streaming_data = []\n            client.read_until_close(self.stop,\n                                    streaming_callback=streaming_data.append)\n            data = self.wait()\n            self.assertEqual(b'', data)\n            self.assertEqual(b''.join(streaming_data), b\"1234\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_large_read_until(self):\n        # Performance test: read_until used to have a quadratic component\n        # so a read_until of 4MB would take 8 seconds; now it takes 0.25\n        # seconds.\n        server, client = self.make_iostream_pair()\n        try:\n            # This test fails on pypy with ssl.  I think it's because\n            # pypy's gc defeats moves objects, breaking the\n            # \"frozen write buffer\" assumption.\n            if (isinstance(server, SSLIOStream) and\n                    platform.python_implementation() == 'PyPy'):\n                raise unittest.SkipTest(\n                    \"pypy gc causes problems with openssl\")\n            NUM_KB = 4096\n            for i in range(NUM_KB):\n                client.write(b\"A\" * 1024)\n            client.write(b\"\\r\\n\")\n            server.read_until(b\"\\r\\n\", self.stop)\n            data = self.wait()\n            self.assertEqual(len(data), NUM_KB * 1024 + 2)\n        finally:\n            server.close()\n            client.close()\n\n    def test_close_callback_with_pending_read(self):\n        # Regression test for a bug that was introduced in 2.3\n        # where the IOStream._close_callback would never be called\n        # if there were pending reads.\n        OK = b\"OK\\r\\n\"\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(OK)\n            client.read_until(b\"\\r\\n\", self.stop)\n            res = self.wait()\n            self.assertEqual(res, OK)\n\n            server.close()\n            client.read_until(b\"\\r\\n\", lambda x: x)\n            # If _close_callback (self.stop) is not called,\n            # an AssertionError: Async operation timed out after 5 seconds\n            # will be raised.\n            res = self.wait()\n            self.assertTrue(res is None)\n        finally:\n            server.close()\n            client.close()\n\n    @skipIfNonUnix\n    def test_inline_read_error(self):\n        # An error on an inline read is raised without logging (on the\n        # assumption that it will eventually be noticed or logged further\n        # up the stack).\n        #\n        # This test is posix-only because windows os.close() doesn't work\n        # on socket FDs, but we can't close the socket object normally\n        # because we won't get the error we want if the socket knows\n        # it's closed.\n        server, client = self.make_iostream_pair()\n        try:\n            os.close(server.socket.fileno())\n            with self.assertRaises(socket.error):\n                server.read_bytes(1, lambda data: None)\n        finally:\n            server.close()\n            client.close()\n\n    def test_async_read_error_logging(self):\n        # Socket errors on asynchronous reads should be logged (but only\n        # once).\n        server, client = self.make_iostream_pair()\n        server.set_close_callback(self.stop)\n        try:\n            # Start a read that will be fullfilled asynchronously.\n            server.read_bytes(1, lambda data: None)\n            client.write(b'a')\n            # Stub out read_from_fd to make it fail.\n\n            def fake_read_from_fd():\n                os.close(server.socket.fileno())\n                server.__class__.read_from_fd(server)\n            server.read_from_fd = fake_read_from_fd\n            # This log message is from _handle_read (not read_from_fd).\n            with ExpectLog(gen_log, \"error on read\"):\n                self.wait()\n        finally:\n            server.close()\n            client.close()\n\n    def test_future_close_callback(self):\n        # Regression test for interaction between the Future read interfaces\n        # and IOStream._maybe_add_error_listener.\n        server, client = self.make_iostream_pair()\n        closed = [False]\n        def close_callback():\n            closed[0] = True\n            self.stop()\n        server.set_close_callback(close_callback)\n        try:\n            client.write(b'a')\n            future = server.read_bytes(1)\n            self.io_loop.add_future(future, self.stop)\n            self.assertEqual(self.wait().result(), b'a')\n            self.assertFalse(closed[0])\n            client.close()\n            self.wait()\n            self.assertTrue(closed[0])\n        finally:\n            server.close()\n            client.close()\n\n\nclass TestIOStreamWebHTTP(TestIOStreamWebMixin, AsyncHTTPTestCase):\n    def _make_client_iostream(self):\n        return IOStream(socket.socket(), io_loop=self.io_loop)\n\n\nclass TestIOStreamWebHTTPS(TestIOStreamWebMixin, AsyncHTTPSTestCase):\n    def _make_client_iostream(self):\n        return SSLIOStream(socket.socket(), io_loop=self.io_loop)\n\n\nclass TestIOStream(TestIOStreamMixin, AsyncTestCase):\n    def _make_server_iostream(self, connection, **kwargs):\n        return IOStream(connection, **kwargs)\n\n    def _make_client_iostream(self, connection, **kwargs):\n        return IOStream(connection, **kwargs)\n\n\nclass TestIOStreamSSL(TestIOStreamMixin, AsyncTestCase):\n    def _make_server_iostream(self, connection, **kwargs):\n        ssl_options = dict(\n            certfile=os.path.join(os.path.dirname(__file__), 'test.crt'),\n            keyfile=os.path.join(os.path.dirname(__file__), 'test.key'),\n        )\n        connection = ssl.wrap_socket(connection,\n                                     server_side=True,\n                                     do_handshake_on_connect=False,\n                                     **ssl_options)\n        return SSLIOStream(connection, io_loop=self.io_loop, **kwargs)\n\n    def _make_client_iostream(self, connection, **kwargs):\n        return SSLIOStream(connection, io_loop=self.io_loop, **kwargs)\n\n\n# This will run some tests that are basically redundant but it's the\n# simplest way to make sure that it works to pass an SSLContext\n# instead of an ssl_options dict to the SSLIOStream constructor.\n@unittest.skipIf(not hasattr(ssl, 'SSLContext'), 'ssl.SSLContext not present')\nclass TestIOStreamSSLContext(TestIOStreamMixin, AsyncTestCase):\n    def _make_server_iostream(self, connection, **kwargs):\n        context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)\n        context.load_cert_chain(\n            os.path.join(os.path.dirname(__file__), 'test.crt'),\n            os.path.join(os.path.dirname(__file__), 'test.key'))\n        connection = ssl_wrap_socket(connection, context,\n                                     server_side=True,\n                                     do_handshake_on_connect=False)\n        return SSLIOStream(connection, io_loop=self.io_loop, **kwargs)\n\n    def _make_client_iostream(self, connection, **kwargs):\n        context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)\n        return SSLIOStream(connection, io_loop=self.io_loop,\n                           ssl_options=context, **kwargs)\n\n\n@skipIfNonUnix\nclass TestPipeIOStream(AsyncTestCase):\n    def test_pipe_iostream(self):\n        r, w = os.pipe()\n\n        rs = PipeIOStream(r, io_loop=self.io_loop)\n        ws = PipeIOStream(w, io_loop=self.io_loop)\n\n        ws.write(b\"hel\")\n        ws.write(b\"lo world\")\n\n        rs.read_until(b' ', callback=self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"hello \")\n\n        rs.read_bytes(3, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"wor\")\n\n        ws.close()\n\n        rs.read_until_close(self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"ld\")\n\n        rs.close()\n\n    def test_pipe_iostream_big_write(self):\n        r, w = os.pipe()\n\n        rs = PipeIOStream(r, io_loop=self.io_loop)\n        ws = PipeIOStream(w, io_loop=self.io_loop)\n\n        NUM_BYTES = 1048576\n\n        # Write 1MB of data, which should fill the buffer\n        ws.write(b\"1\" * NUM_BYTES)\n\n        rs.read_bytes(NUM_BYTES, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"1\" * NUM_BYTES)\n\n        ws.close()\n        rs.close()\n",
            "header": {
                "file": {
                    "path": "tornado/test/iostream_test.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "35a4bd85",
                "new_commit_hash": "24b37b81",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/tornado/test/iostream_test.py"
            },
            "plus_file": {
                "path": "b/tornado/test/iostream_test.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 511,
                            "length": 6
                        },
                        "new_range": {
                            "start": 511,
                            "length": 28
                        },
                        "section": "class TestIOStreamMixin(object):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "            server.close()",
                                "type": "context"
                            },
                            {
                                "content": "            client.close()",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def test_future_close_callback(self):",
                                "type": "added"
                            },
                            {
                                "content": "        # Regression test for interaction between the Future read interfaces",
                                "type": "added"
                            },
                            {
                                "content": "        # and IOStream._maybe_add_error_listener.",
                                "type": "added"
                            },
                            {
                                "content": "        server, client = self.make_iostream_pair()",
                                "type": "added"
                            },
                            {
                                "content": "        closed = [False]",
                                "type": "added"
                            },
                            {
                                "content": "        def close_callback():",
                                "type": "added"
                            },
                            {
                                "content": "            closed[0] = True",
                                "type": "added"
                            },
                            {
                                "content": "            self.stop()",
                                "type": "added"
                            },
                            {
                                "content": "        server.set_close_callback(close_callback)",
                                "type": "added"
                            },
                            {
                                "content": "        try:",
                                "type": "added"
                            },
                            {
                                "content": "            client.write(b'a')",
                                "type": "added"
                            },
                            {
                                "content": "            future = server.read_bytes(1)",
                                "type": "added"
                            },
                            {
                                "content": "            self.io_loop.add_future(future, self.stop)",
                                "type": "added"
                            },
                            {
                                "content": "            self.assertEqual(self.wait().result(), b'a')",
                                "type": "added"
                            },
                            {
                                "content": "            self.assertFalse(closed[0])",
                                "type": "added"
                            },
                            {
                                "content": "            client.close()",
                                "type": "added"
                            },
                            {
                                "content": "            self.wait()",
                                "type": "added"
                            },
                            {
                                "content": "            self.assertTrue(closed[0])",
                                "type": "added"
                            },
                            {
                                "content": "        finally:",
                                "type": "added"
                            },
                            {
                                "content": "            server.close()",
                                "type": "added"
                            },
                            {
                                "content": "            client.close()",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "class TestIOStreamWebHTTP(TestIOStreamWebMixin, AsyncHTTPTestCase):",
                                "type": "context"
                            },
                            {
                                "content": "    def _make_client_iostream(self):",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tornado/test/iostream_test.py",
                            "type": "class",
                            "name": "TestIOStreamMixin",
                            "content": "class TestIOStreamMixin(object):\n    def _make_server_iostream(self, connection, **kwargs):\n        raise NotImplementedError()\n\n    def _make_client_iostream(self, connection, **kwargs):\n        raise NotImplementedError()\n\n    def make_iostream_pair(self, **kwargs):\n        listener, port = bind_unused_port()\n        streams = [None, None]\n\n        def accept_callback(connection, address):\n            streams[0] = self._make_server_iostream(connection, **kwargs)\n            self.stop()\n\n        def connect_callback():\n            streams[1] = client_stream\n            self.stop()\n        netutil.add_accept_handler(listener, accept_callback,\n                                   io_loop=self.io_loop)\n        client_stream = self._make_client_iostream(socket.socket(), **kwargs)\n        client_stream.connect(('127.0.0.1', port),\n                              callback=connect_callback)\n        self.wait(condition=lambda: all(streams))\n        self.io_loop.remove_handler(listener.fileno())\n        listener.close()\n        return streams\n\n    def test_streaming_callback_with_data_in_buffer(self):\n        server, client = self.make_iostream_pair()\n        client.write(b\"abcd\\r\\nefgh\")\n        server.read_until(b\"\\r\\n\", self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"abcd\\r\\n\")\n\n        def closed_callback(chunk):\n            self.fail()\n        server.read_until_close(callback=closed_callback,\n                                streaming_callback=self.stop)\n        # self.io_loop.add_timeout(self.io_loop.time() + 0.01, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"efgh\")\n        server.close()\n        client.close()\n\n    def test_write_zero_bytes(self):\n        # Attempting to write zero bytes should run the callback without\n        # going into an infinite loop.\n        server, client = self.make_iostream_pair()\n        server.write(b'', callback=self.stop)\n        self.wait()\n        # As a side effect, the stream is now listening for connection\n        # close (if it wasn't already), but is not listening for writes\n        self.assertEqual(server._state, IOLoop.READ | IOLoop.ERROR)\n        server.close()\n        client.close()\n\n    def test_connection_refused(self):\n        # When a connection is refused, the connect callback should not\n        # be run.  (The kqueue IOLoop used to behave differently from the\n        # epoll IOLoop in this respect)\n        server_socket, port = bind_unused_port()\n        server_socket.close()\n        stream = IOStream(socket.socket(), self.io_loop)\n        self.connect_called = False\n\n        def connect_callback():\n            self.connect_called = True\n        stream.set_close_callback(self.stop)\n        # log messages vary by platform and ioloop implementation\n        with ExpectLog(gen_log, \".*\", required=False):\n            stream.connect((\"localhost\", port), connect_callback)\n            self.wait()\n        self.assertFalse(self.connect_called)\n        self.assertTrue(isinstance(stream.error, socket.error), stream.error)\n        if sys.platform != 'cygwin':\n            # cygwin's errnos don't match those used on native windows python\n            self.assertEqual(stream.error.args[0], errno.ECONNREFUSED)\n\n    def test_gaierror(self):\n        # Test that IOStream sets its exc_info on getaddrinfo error\n        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)\n        stream = IOStream(s, io_loop=self.io_loop)\n        stream.set_close_callback(self.stop)\n        # To reliably generate a gaierror we use a malformed domain name\n        # instead of a name that's simply unlikely to exist (since\n        # opendns and some ISPs return bogus addresses for nonexistent\n        # domains instead of the proper error codes).\n        with ExpectLog(gen_log, \"Connect error\"):\n            stream.connect(('an invalid domain', 54321))\n            self.assertTrue(isinstance(stream.error, socket.gaierror), stream.error)\n\n    def test_read_callback_error(self):\n        # Test that IOStream sets its exc_info when a read callback throws\n        server, client = self.make_iostream_pair()\n        try:\n            server.set_close_callback(self.stop)\n            with ExpectLog(\n                app_log, \"(Uncaught exception|Exception in callback)\"\n            ):\n                # Clear ExceptionStackContext so IOStream catches error\n                with NullContext():\n                    server.read_bytes(1, callback=lambda data: 1 / 0)\n                client.write(b\"1\")\n                self.wait()\n            self.assertTrue(isinstance(server.error, ZeroDivisionError))\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_callback(self):\n        server, client = self.make_iostream_pair()\n        try:\n            chunks = []\n            final_called = []\n\n            def streaming_callback(data):\n                chunks.append(data)\n                self.stop()\n\n            def final_callback(data):\n                self.assertFalse(data)\n                final_called.append(True)\n                self.stop()\n            server.read_bytes(6, callback=final_callback,\n                              streaming_callback=streaming_callback)\n            client.write(b\"1234\")\n            self.wait(condition=lambda: chunks)\n            client.write(b\"5678\")\n            self.wait(condition=lambda: final_called)\n            self.assertEqual(chunks, [b\"1234\", b\"56\"])\n\n            # the rest of the last chunk is still in the buffer\n            server.read_bytes(2, callback=self.stop)\n            data = self.wait()\n            self.assertEqual(data, b\"78\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_until_close(self):\n        server, client = self.make_iostream_pair()\n        try:\n            chunks = []\n            closed = [False]\n\n            def streaming_callback(data):\n                chunks.append(data)\n                self.stop()\n            def close_callback(data):\n                assert not data, data\n                closed[0] = True\n                self.stop()\n            client.read_until_close(callback=close_callback,\n                                    streaming_callback=streaming_callback)\n            server.write(b\"1234\")\n            self.wait(condition=lambda: len(chunks) == 1)\n            server.write(b\"5678\", self.stop)\n            self.wait()\n            server.close()\n            self.wait(condition=lambda: closed[0])\n            self.assertEqual(chunks, [b\"1234\", b\"5678\"])\n        finally:\n            server.close()\n            client.close()\n\n    def test_delayed_close_callback(self):\n        # The scenario:  Server closes the connection while there is a pending\n        # read that can be served out of buffered data.  The client does not\n        # run the close_callback as soon as it detects the close, but rather\n        # defers it until after the buffered read has finished.\n        server, client = self.make_iostream_pair()\n        try:\n            client.set_close_callback(self.stop)\n            server.write(b\"12\")\n            chunks = []\n\n            def callback1(data):\n                chunks.append(data)\n                client.read_bytes(1, callback2)\n                server.close()\n\n            def callback2(data):\n                chunks.append(data)\n            client.read_bytes(1, callback1)\n            self.wait()  # stopped by close_callback\n            self.assertEqual(chunks, [b\"1\", b\"2\"])\n        finally:\n            server.close()\n            client.close()\n\n    def test_future_delayed_close_callback(self):\n        # Same as test_delayed_close_callback, but with the future interface.\n        server, client = self.make_iostream_pair()\n        # We can't call make_iostream_pair inside a gen_test function\n        # because the ioloop is not reentrant.\n        @gen_test\n        def f(self):\n            server.write(b\"12\")\n            chunks = []\n            chunks.append((yield client.read_bytes(1)))\n            server.close()\n            chunks.append((yield client.read_bytes(1)))\n            self.assertEqual(chunks, [b\"1\", b\"2\"])\n        try:\n            f(self)\n        finally:\n            server.close()\n            client.close()\n\n    def test_close_buffered_data(self):\n        # Similar to the previous test, but with data stored in the OS's\n        # socket buffers instead of the IOStream's read buffer.  Out-of-band\n        # close notifications must be delayed until all data has been\n        # drained into the IOStream buffer. (epoll used to use out-of-band\n        # close events with EPOLLRDHUP, but no longer)\n        #\n        # This depends on the read_chunk_size being smaller than the\n        # OS socket buffer, so make it small.\n        server, client = self.make_iostream_pair(read_chunk_size=256)\n        try:\n            server.write(b\"A\" * 512)\n            client.read_bytes(256, self.stop)\n            data = self.wait()\n            self.assertEqual(b\"A\" * 256, data)\n            server.close()\n            # Allow the close to propagate to the client side of the\n            # connection.  Using add_callback instead of add_timeout\n            # doesn't seem to work, even with multiple iterations\n            self.io_loop.add_timeout(self.io_loop.time() + 0.01, self.stop)\n            self.wait()\n            client.read_bytes(256, self.stop)\n            data = self.wait()\n            self.assertEqual(b\"A\" * 256, data)\n        finally:\n            server.close()\n            client.close()\n\n    def test_read_until_close_after_close(self):\n        # Similar to test_delayed_close_callback, but read_until_close takes\n        # a separate code path so test it separately.\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(b\"1234\")\n            server.close()\n            self.wait()\n            client.read_until_close(self.stop)\n            data = self.wait()\n            self.assertEqual(data, b\"1234\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_read_until_close_after_close(self):\n        # Same as the preceding test but with a streaming_callback.\n        # All data should go through the streaming callback,\n        # and the final read callback just gets an empty string.\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(b\"1234\")\n            server.close()\n            self.wait()\n            streaming_data = []\n            client.read_until_close(self.stop,\n                                    streaming_callback=streaming_data.append)\n            data = self.wait()\n            self.assertEqual(b'', data)\n            self.assertEqual(b''.join(streaming_data), b\"1234\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_large_read_until(self):\n        # Performance test: read_until used to have a quadratic component\n        # so a read_until of 4MB would take 8 seconds; now it takes 0.25\n        # seconds.\n        server, client = self.make_iostream_pair()\n        try:\n            # This test fails on pypy with ssl.  I think it's because\n            # pypy's gc defeats moves objects, breaking the\n            # \"frozen write buffer\" assumption.\n            if (isinstance(server, SSLIOStream) and\n                    platform.python_implementation() == 'PyPy'):\n                raise unittest.SkipTest(\n                    \"pypy gc causes problems with openssl\")\n            NUM_KB = 4096\n            for i in range(NUM_KB):\n                client.write(b\"A\" * 1024)\n            client.write(b\"\\r\\n\")\n            server.read_until(b\"\\r\\n\", self.stop)\n            data = self.wait()\n            self.assertEqual(len(data), NUM_KB * 1024 + 2)\n        finally:\n            server.close()\n            client.close()\n\n    def test_close_callback_with_pending_read(self):\n        # Regression test for a bug that was introduced in 2.3\n        # where the IOStream._close_callback would never be called\n        # if there were pending reads.\n        OK = b\"OK\\r\\n\"\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(OK)\n            client.read_until(b\"\\r\\n\", self.stop)\n            res = self.wait()\n            self.assertEqual(res, OK)\n\n            server.close()\n            client.read_until(b\"\\r\\n\", lambda x: x)\n            # If _close_callback (self.stop) is not called,\n            # an AssertionError: Async operation timed out after 5 seconds\n            # will be raised.\n            res = self.wait()\n            self.assertTrue(res is None)\n        finally:\n            server.close()\n            client.close()\n\n    @skipIfNonUnix\n    def test_inline_read_error(self):\n        # An error on an inline read is raised without logging (on the\n        # assumption that it will eventually be noticed or logged further\n        # up the stack).\n        #\n        # This test is posix-only because windows os.close() doesn't work\n        # on socket FDs, but we can't close the socket object normally\n        # because we won't get the error we want if the socket knows\n        # it's closed.\n        server, client = self.make_iostream_pair()\n        try:\n            os.close(server.socket.fileno())\n            with self.assertRaises(socket.error):\n                server.read_bytes(1, lambda data: None)\n        finally:\n            server.close()\n            client.close()\n\n    def test_async_read_error_logging(self):\n        # Socket errors on asynchronous reads should be logged (but only\n        # once).\n        server, client = self.make_iostream_pair()\n        server.set_close_callback(self.stop)\n        try:\n            # Start a read that will be fullfilled asynchronously.\n            server.read_bytes(1, lambda data: None)\n            client.write(b'a')\n            # Stub out read_from_fd to make it fail.\n\n            def fake_read_from_fd():\n                os.close(server.socket.fileno())\n                server.__class__.read_from_fd(server)\n            server.read_from_fd = fake_read_from_fd\n            # This log message is from _handle_read (not read_from_fd).\n            with ExpectLog(gen_log, \"error on read\"):\n                self.wait()\n        finally:\n            server.close()\n            client.close()\n\n    def test_future_close_callback(self):\n        # Regression test for interaction between the Future read interfaces\n        # and IOStream._maybe_add_error_listener.\n        server, client = self.make_iostream_pair()\n        closed = [False]\n        def close_callback():\n            closed[0] = True\n            self.stop()\n        server.set_close_callback(close_callback)\n        try:\n            client.write(b'a')\n            future = server.read_bytes(1)\n            self.io_loop.add_future(future, self.stop)\n            self.assertEqual(self.wait().result(), b'a')\n            self.assertFalse(closed[0])\n            client.close()\n            self.wait()\n            self.assertTrue(closed[0])\n        finally:\n            server.close()\n            client.close()",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 151,
                            "end_lineno": 534,
                            "parent": null
                        }
                    ],
                    "added_entities": [
                        {
                            "file_name": "tornado/test/iostream_test.py",
                            "type": "method",
                            "name": "TestIOStreamMixin.test_future_close_callback",
                            "content": "class TestIOStreamMixin(object):\n    def _make_server_iostream(self, connection, **kwargs):\n        raise NotImplementedError()\n\n    def _make_client_iostream(self, connection, **kwargs):\n        raise NotImplementedError()\n\n    def make_iostream_pair(self, **kwargs):\n        listener, port = bind_unused_port()\n        streams = [None, None]\n\n        def accept_callback(connection, address):\n            streams[0] = self._make_server_iostream(connection, **kwargs)\n            self.stop()\n\n        def connect_callback():\n            streams[1] = client_stream\n            self.stop()\n        netutil.add_accept_handler(listener, accept_callback,\n                                   io_loop=self.io_loop)\n        client_stream = self._make_client_iostream(socket.socket(), **kwargs)\n        client_stream.connect(('127.0.0.1', port),\n                              callback=connect_callback)\n        self.wait(condition=lambda: all(streams))\n        self.io_loop.remove_handler(listener.fileno())\n        listener.close()\n        return streams\n\n    def test_streaming_callback_with_data_in_buffer(self):\n        server, client = self.make_iostream_pair()\n        client.write(b\"abcd\\r\\nefgh\")\n        server.read_until(b\"\\r\\n\", self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"abcd\\r\\n\")\n\n        def closed_callback(chunk):\n            self.fail()\n        server.read_until_close(callback=closed_callback,\n                                streaming_callback=self.stop)\n        # self.io_loop.add_timeout(self.io_loop.time() + 0.01, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"efgh\")\n        server.close()\n        client.close()\n\n    def test_write_zero_bytes(self):\n        # Attempting to write zero bytes should run the callback without\n        # going into an infinite loop.\n        server, client = self.make_iostream_pair()\n        server.write(b'', callback=self.stop)\n        self.wait()\n        # As a side effect, the stream is now listening for connection\n        # close (if it wasn't already), but is not listening for writes\n        self.assertEqual(server._state, IOLoop.READ | IOLoop.ERROR)\n        server.close()\n        client.close()\n\n    def test_connection_refused(self):\n        # When a connection is refused, the connect callback should not\n        # be run.  (The kqueue IOLoop used to behave differently from the\n        # epoll IOLoop in this respect)\n        server_socket, port = bind_unused_port()\n        server_socket.close()\n        stream = IOStream(socket.socket(), self.io_loop)\n        self.connect_called = False\n\n        def connect_callback():\n            self.connect_called = True\n        stream.set_close_callback(self.stop)\n        # log messages vary by platform and ioloop implementation\n        with ExpectLog(gen_log, \".*\", required=False):\n            stream.connect((\"localhost\", port), connect_callback)\n            self.wait()\n        self.assertFalse(self.connect_called)\n        self.assertTrue(isinstance(stream.error, socket.error), stream.error)\n        if sys.platform != 'cygwin':\n            # cygwin's errnos don't match those used on native windows python\n            self.assertEqual(stream.error.args[0], errno.ECONNREFUSED)\n\n    def test_gaierror(self):\n        # Test that IOStream sets its exc_info on getaddrinfo error\n        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)\n        stream = IOStream(s, io_loop=self.io_loop)\n        stream.set_close_callback(self.stop)\n        # To reliably generate a gaierror we use a malformed domain name\n        # instead of a name that's simply unlikely to exist (since\n        # opendns and some ISPs return bogus addresses for nonexistent\n        # domains instead of the proper error codes).\n        with ExpectLog(gen_log, \"Connect error\"):\n            stream.connect(('an invalid domain', 54321))\n            self.assertTrue(isinstance(stream.error, socket.gaierror), stream.error)\n\n    def test_read_callback_error(self):\n        # Test that IOStream sets its exc_info when a read callback throws\n        server, client = self.make_iostream_pair()\n        try:\n            server.set_close_callback(self.stop)\n            with ExpectLog(\n                app_log, \"(Uncaught exception|Exception in callback)\"\n            ):\n                # Clear ExceptionStackContext so IOStream catches error\n                with NullContext():\n                    server.read_bytes(1, callback=lambda data: 1 / 0)\n                client.write(b\"1\")\n                self.wait()\n            self.assertTrue(isinstance(server.error, ZeroDivisionError))\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_callback(self):\n        server, client = self.make_iostream_pair()\n        try:\n            chunks = []\n            final_called = []\n\n            def streaming_callback(data):\n                chunks.append(data)\n                self.stop()\n\n            def final_callback(data):\n                self.assertFalse(data)\n                final_called.append(True)\n                self.stop()\n            server.read_bytes(6, callback=final_callback,\n                              streaming_callback=streaming_callback)\n            client.write(b\"1234\")\n            self.wait(condition=lambda: chunks)\n            client.write(b\"5678\")\n            self.wait(condition=lambda: final_called)\n            self.assertEqual(chunks, [b\"1234\", b\"56\"])\n\n            # the rest of the last chunk is still in the buffer\n            server.read_bytes(2, callback=self.stop)\n            data = self.wait()\n            self.assertEqual(data, b\"78\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_until_close(self):\n        server, client = self.make_iostream_pair()\n        try:\n            chunks = []\n            closed = [False]\n\n            def streaming_callback(data):\n                chunks.append(data)\n                self.stop()\n            def close_callback(data):\n                assert not data, data\n                closed[0] = True\n                self.stop()\n            client.read_until_close(callback=close_callback,\n                                    streaming_callback=streaming_callback)\n            server.write(b\"1234\")\n            self.wait(condition=lambda: len(chunks) == 1)\n            server.write(b\"5678\", self.stop)\n            self.wait()\n            server.close()\n            self.wait(condition=lambda: closed[0])\n            self.assertEqual(chunks, [b\"1234\", b\"5678\"])\n        finally:\n            server.close()\n            client.close()\n\n    def test_delayed_close_callback(self):\n        # The scenario:  Server closes the connection while there is a pending\n        # read that can be served out of buffered data.  The client does not\n        # run the close_callback as soon as it detects the close, but rather\n        # defers it until after the buffered read has finished.\n        server, client = self.make_iostream_pair()\n        try:\n            client.set_close_callback(self.stop)\n            server.write(b\"12\")\n            chunks = []\n\n            def callback1(data):\n                chunks.append(data)\n                client.read_bytes(1, callback2)\n                server.close()\n\n            def callback2(data):\n                chunks.append(data)\n            client.read_bytes(1, callback1)\n            self.wait()  # stopped by close_callback\n            self.assertEqual(chunks, [b\"1\", b\"2\"])\n        finally:\n            server.close()\n            client.close()\n\n    def test_future_delayed_close_callback(self):\n        # Same as test_delayed_close_callback, but with the future interface.\n        server, client = self.make_iostream_pair()\n        # We can't call make_iostream_pair inside a gen_test function\n        # because the ioloop is not reentrant.\n        @gen_test\n        def f(self):\n            server.write(b\"12\")\n            chunks = []\n            chunks.append((yield client.read_bytes(1)))\n            server.close()\n            chunks.append((yield client.read_bytes(1)))\n            self.assertEqual(chunks, [b\"1\", b\"2\"])\n        try:\n            f(self)\n        finally:\n            server.close()\n            client.close()\n\n    def test_close_buffered_data(self):\n        # Similar to the previous test, but with data stored in the OS's\n        # socket buffers instead of the IOStream's read buffer.  Out-of-band\n        # close notifications must be delayed until all data has been\n        # drained into the IOStream buffer. (epoll used to use out-of-band\n        # close events with EPOLLRDHUP, but no longer)\n        #\n        # This depends on the read_chunk_size being smaller than the\n        # OS socket buffer, so make it small.\n        server, client = self.make_iostream_pair(read_chunk_size=256)\n        try:\n            server.write(b\"A\" * 512)\n            client.read_bytes(256, self.stop)\n            data = self.wait()\n            self.assertEqual(b\"A\" * 256, data)\n            server.close()\n            # Allow the close to propagate to the client side of the\n            # connection.  Using add_callback instead of add_timeout\n            # doesn't seem to work, even with multiple iterations\n            self.io_loop.add_timeout(self.io_loop.time() + 0.01, self.stop)\n            self.wait()\n            client.read_bytes(256, self.stop)\n            data = self.wait()\n            self.assertEqual(b\"A\" * 256, data)\n        finally:\n            server.close()\n            client.close()\n\n    def test_read_until_close_after_close(self):\n        # Similar to test_delayed_close_callback, but read_until_close takes\n        # a separate code path so test it separately.\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(b\"1234\")\n            server.close()\n            self.wait()\n            client.read_until_close(self.stop)\n            data = self.wait()\n            self.assertEqual(data, b\"1234\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_read_until_close_after_close(self):\n        # Same as the preceding test but with a streaming_callback.\n        # All data should go through the streaming callback,\n        # and the final read callback just gets an empty string.\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(b\"1234\")\n            server.close()\n            self.wait()\n            streaming_data = []\n            client.read_until_close(self.stop,\n                                    streaming_callback=streaming_data.append)\n            data = self.wait()\n            self.assertEqual(b'', data)\n            self.assertEqual(b''.join(streaming_data), b\"1234\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_large_read_until(self):\n        # Performance test: read_until used to have a quadratic component\n        # so a read_until of 4MB would take 8 seconds; now it takes 0.25\n        # seconds.\n        server, client = self.make_iostream_pair()\n        try:\n            # This test fails on pypy with ssl.  I think it's because\n            # pypy's gc defeats moves objects, breaking the\n            # \"frozen write buffer\" assumption.\n            if (isinstance(server, SSLIOStream) and\n                    platform.python_implementation() == 'PyPy'):\n                raise unittest.SkipTest(\n                    \"pypy gc causes problems with openssl\")\n            NUM_KB = 4096\n            for i in range(NUM_KB):\n                client.write(b\"A\" * 1024)\n            client.write(b\"\\r\\n\")\n            server.read_until(b\"\\r\\n\", self.stop)\n            data = self.wait()\n            self.assertEqual(len(data), NUM_KB * 1024 + 2)\n        finally:\n            server.close()\n            client.close()\n\n    def test_close_callback_with_pending_read(self):\n        # Regression test for a bug that was introduced in 2.3\n        # where the IOStream._close_callback would never be called\n        # if there were pending reads.\n        OK = b\"OK\\r\\n\"\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(OK)\n            client.read_until(b\"\\r\\n\", self.stop)\n            res = self.wait()\n            self.assertEqual(res, OK)\n\n            server.close()\n            client.read_until(b\"\\r\\n\", lambda x: x)\n            # If _close_callback (self.stop) is not called,\n            # an AssertionError: Async operation timed out after 5 seconds\n            # will be raised.\n            res = self.wait()\n            self.assertTrue(res is None)\n        finally:\n            server.close()\n            client.close()\n\n    @skipIfNonUnix\n    def test_inline_read_error(self):\n        # An error on an inline read is raised without logging (on the\n        # assumption that it will eventually be noticed or logged further\n        # up the stack).\n        #\n        # This test is posix-only because windows os.close() doesn't work\n        # on socket FDs, but we can't close the socket object normally\n        # because we won't get the error we want if the socket knows\n        # it's closed.\n        server, client = self.make_iostream_pair()\n        try:\n            os.close(server.socket.fileno())\n            with self.assertRaises(socket.error):\n                server.read_bytes(1, lambda data: None)\n        finally:\n            server.close()\n            client.close()\n\n    def test_async_read_error_logging(self):\n        # Socket errors on asynchronous reads should be logged (but only\n        # once).\n        server, client = self.make_iostream_pair()\n        server.set_close_callback(self.stop)\n        try:\n            # Start a read that will be fullfilled asynchronously.\n            server.read_bytes(1, lambda data: None)\n            client.write(b'a')\n            # Stub out read_from_fd to make it fail.\n\n            def fake_read_from_fd():\n                os.close(server.socket.fileno())\n                server.__class__.read_from_fd(server)\n            server.read_from_fd = fake_read_from_fd\n            # This log message is from _handle_read (not read_from_fd).\n            with ExpectLog(gen_log, \"error on read\"):\n                self.wait()\n        finally:\n            server.close()\n            client.close()\n\n    def test_future_close_callback(self):\n        # Regression test for interaction between the Future read interfaces\n        # and IOStream._maybe_add_error_listener.\n        server, client = self.make_iostream_pair()\n        closed = [False]\n        def close_callback():\n            closed[0] = True\n            self.stop()\n        server.set_close_callback(close_callback)\n        try:\n            client.write(b'a')\n            future = server.read_bytes(1)\n            self.io_loop.add_future(future, self.stop)\n            self.assertEqual(self.wait().result(), b'a')\n            self.assertFalse(closed[0])\n            client.close()\n            self.wait()\n            self.assertTrue(closed[0])\n        finally:\n            server.close()\n            client.close()",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 514,
                            "end_lineno": 534,
                            "parent": {
                                "file_name": "tornado/test/iostream_test.py",
                                "type": "class",
                                "name": "TestIOStreamMixin",
                                "content": "class TestIOStreamMixin(object):\n    def _make_server_iostream(self, connection, **kwargs):\n        raise NotImplementedError()\n\n    def _make_client_iostream(self, connection, **kwargs):\n        raise NotImplementedError()\n\n    def make_iostream_pair(self, **kwargs):\n        listener, port = bind_unused_port()\n        streams = [None, None]\n\n        def accept_callback(connection, address):\n            streams[0] = self._make_server_iostream(connection, **kwargs)\n            self.stop()\n\n        def connect_callback():\n            streams[1] = client_stream\n            self.stop()\n        netutil.add_accept_handler(listener, accept_callback,\n                                   io_loop=self.io_loop)\n        client_stream = self._make_client_iostream(socket.socket(), **kwargs)\n        client_stream.connect(('127.0.0.1', port),\n                              callback=connect_callback)\n        self.wait(condition=lambda: all(streams))\n        self.io_loop.remove_handler(listener.fileno())\n        listener.close()\n        return streams\n\n    def test_streaming_callback_with_data_in_buffer(self):\n        server, client = self.make_iostream_pair()\n        client.write(b\"abcd\\r\\nefgh\")\n        server.read_until(b\"\\r\\n\", self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"abcd\\r\\n\")\n\n        def closed_callback(chunk):\n            self.fail()\n        server.read_until_close(callback=closed_callback,\n                                streaming_callback=self.stop)\n        # self.io_loop.add_timeout(self.io_loop.time() + 0.01, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"efgh\")\n        server.close()\n        client.close()\n\n    def test_write_zero_bytes(self):\n        # Attempting to write zero bytes should run the callback without\n        # going into an infinite loop.\n        server, client = self.make_iostream_pair()\n        server.write(b'', callback=self.stop)\n        self.wait()\n        # As a side effect, the stream is now listening for connection\n        # close (if it wasn't already), but is not listening for writes\n        self.assertEqual(server._state, IOLoop.READ | IOLoop.ERROR)\n        server.close()\n        client.close()\n\n    def test_connection_refused(self):\n        # When a connection is refused, the connect callback should not\n        # be run.  (The kqueue IOLoop used to behave differently from the\n        # epoll IOLoop in this respect)\n        server_socket, port = bind_unused_port()\n        server_socket.close()\n        stream = IOStream(socket.socket(), self.io_loop)\n        self.connect_called = False\n\n        def connect_callback():\n            self.connect_called = True\n        stream.set_close_callback(self.stop)\n        # log messages vary by platform and ioloop implementation\n        with ExpectLog(gen_log, \".*\", required=False):\n            stream.connect((\"localhost\", port), connect_callback)\n            self.wait()\n        self.assertFalse(self.connect_called)\n        self.assertTrue(isinstance(stream.error, socket.error), stream.error)\n        if sys.platform != 'cygwin':\n            # cygwin's errnos don't match those used on native windows python\n            self.assertEqual(stream.error.args[0], errno.ECONNREFUSED)\n\n    def test_gaierror(self):\n        # Test that IOStream sets its exc_info on getaddrinfo error\n        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)\n        stream = IOStream(s, io_loop=self.io_loop)\n        stream.set_close_callback(self.stop)\n        # To reliably generate a gaierror we use a malformed domain name\n        # instead of a name that's simply unlikely to exist (since\n        # opendns and some ISPs return bogus addresses for nonexistent\n        # domains instead of the proper error codes).\n        with ExpectLog(gen_log, \"Connect error\"):\n            stream.connect(('an invalid domain', 54321))\n            self.assertTrue(isinstance(stream.error, socket.gaierror), stream.error)\n\n    def test_read_callback_error(self):\n        # Test that IOStream sets its exc_info when a read callback throws\n        server, client = self.make_iostream_pair()\n        try:\n            server.set_close_callback(self.stop)\n            with ExpectLog(\n                app_log, \"(Uncaught exception|Exception in callback)\"\n            ):\n                # Clear ExceptionStackContext so IOStream catches error\n                with NullContext():\n                    server.read_bytes(1, callback=lambda data: 1 / 0)\n                client.write(b\"1\")\n                self.wait()\n            self.assertTrue(isinstance(server.error, ZeroDivisionError))\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_callback(self):\n        server, client = self.make_iostream_pair()\n        try:\n            chunks = []\n            final_called = []\n\n            def streaming_callback(data):\n                chunks.append(data)\n                self.stop()\n\n            def final_callback(data):\n                self.assertFalse(data)\n                final_called.append(True)\n                self.stop()\n            server.read_bytes(6, callback=final_callback,\n                              streaming_callback=streaming_callback)\n            client.write(b\"1234\")\n            self.wait(condition=lambda: chunks)\n            client.write(b\"5678\")\n            self.wait(condition=lambda: final_called)\n            self.assertEqual(chunks, [b\"1234\", b\"56\"])\n\n            # the rest of the last chunk is still in the buffer\n            server.read_bytes(2, callback=self.stop)\n            data = self.wait()\n            self.assertEqual(data, b\"78\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_until_close(self):\n        server, client = self.make_iostream_pair()\n        try:\n            chunks = []\n            closed = [False]\n\n            def streaming_callback(data):\n                chunks.append(data)\n                self.stop()\n            def close_callback(data):\n                assert not data, data\n                closed[0] = True\n                self.stop()\n            client.read_until_close(callback=close_callback,\n                                    streaming_callback=streaming_callback)\n            server.write(b\"1234\")\n            self.wait(condition=lambda: len(chunks) == 1)\n            server.write(b\"5678\", self.stop)\n            self.wait()\n            server.close()\n            self.wait(condition=lambda: closed[0])\n            self.assertEqual(chunks, [b\"1234\", b\"5678\"])\n        finally:\n            server.close()\n            client.close()\n\n    def test_delayed_close_callback(self):\n        # The scenario:  Server closes the connection while there is a pending\n        # read that can be served out of buffered data.  The client does not\n        # run the close_callback as soon as it detects the close, but rather\n        # defers it until after the buffered read has finished.\n        server, client = self.make_iostream_pair()\n        try:\n            client.set_close_callback(self.stop)\n            server.write(b\"12\")\n            chunks = []\n\n            def callback1(data):\n                chunks.append(data)\n                client.read_bytes(1, callback2)\n                server.close()\n\n            def callback2(data):\n                chunks.append(data)\n            client.read_bytes(1, callback1)\n            self.wait()  # stopped by close_callback\n            self.assertEqual(chunks, [b\"1\", b\"2\"])\n        finally:\n            server.close()\n            client.close()\n\n    def test_future_delayed_close_callback(self):\n        # Same as test_delayed_close_callback, but with the future interface.\n        server, client = self.make_iostream_pair()\n        # We can't call make_iostream_pair inside a gen_test function\n        # because the ioloop is not reentrant.\n        @gen_test\n        def f(self):\n            server.write(b\"12\")\n            chunks = []\n            chunks.append((yield client.read_bytes(1)))\n            server.close()\n            chunks.append((yield client.read_bytes(1)))\n            self.assertEqual(chunks, [b\"1\", b\"2\"])\n        try:\n            f(self)\n        finally:\n            server.close()\n            client.close()\n\n    def test_close_buffered_data(self):\n        # Similar to the previous test, but with data stored in the OS's\n        # socket buffers instead of the IOStream's read buffer.  Out-of-band\n        # close notifications must be delayed until all data has been\n        # drained into the IOStream buffer. (epoll used to use out-of-band\n        # close events with EPOLLRDHUP, but no longer)\n        #\n        # This depends on the read_chunk_size being smaller than the\n        # OS socket buffer, so make it small.\n        server, client = self.make_iostream_pair(read_chunk_size=256)\n        try:\n            server.write(b\"A\" * 512)\n            client.read_bytes(256, self.stop)\n            data = self.wait()\n            self.assertEqual(b\"A\" * 256, data)\n            server.close()\n            # Allow the close to propagate to the client side of the\n            # connection.  Using add_callback instead of add_timeout\n            # doesn't seem to work, even with multiple iterations\n            self.io_loop.add_timeout(self.io_loop.time() + 0.01, self.stop)\n            self.wait()\n            client.read_bytes(256, self.stop)\n            data = self.wait()\n            self.assertEqual(b\"A\" * 256, data)\n        finally:\n            server.close()\n            client.close()\n\n    def test_read_until_close_after_close(self):\n        # Similar to test_delayed_close_callback, but read_until_close takes\n        # a separate code path so test it separately.\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(b\"1234\")\n            server.close()\n            self.wait()\n            client.read_until_close(self.stop)\n            data = self.wait()\n            self.assertEqual(data, b\"1234\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_read_until_close_after_close(self):\n        # Same as the preceding test but with a streaming_callback.\n        # All data should go through the streaming callback,\n        # and the final read callback just gets an empty string.\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(b\"1234\")\n            server.close()\n            self.wait()\n            streaming_data = []\n            client.read_until_close(self.stop,\n                                    streaming_callback=streaming_data.append)\n            data = self.wait()\n            self.assertEqual(b'', data)\n            self.assertEqual(b''.join(streaming_data), b\"1234\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_large_read_until(self):\n        # Performance test: read_until used to have a quadratic component\n        # so a read_until of 4MB would take 8 seconds; now it takes 0.25\n        # seconds.\n        server, client = self.make_iostream_pair()\n        try:\n            # This test fails on pypy with ssl.  I think it's because\n            # pypy's gc defeats moves objects, breaking the\n            # \"frozen write buffer\" assumption.\n            if (isinstance(server, SSLIOStream) and\n                    platform.python_implementation() == 'PyPy'):\n                raise unittest.SkipTest(\n                    \"pypy gc causes problems with openssl\")\n            NUM_KB = 4096\n            for i in range(NUM_KB):\n                client.write(b\"A\" * 1024)\n            client.write(b\"\\r\\n\")\n            server.read_until(b\"\\r\\n\", self.stop)\n            data = self.wait()\n            self.assertEqual(len(data), NUM_KB * 1024 + 2)\n        finally:\n            server.close()\n            client.close()\n\n    def test_close_callback_with_pending_read(self):\n        # Regression test for a bug that was introduced in 2.3\n        # where the IOStream._close_callback would never be called\n        # if there were pending reads.\n        OK = b\"OK\\r\\n\"\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(OK)\n            client.read_until(b\"\\r\\n\", self.stop)\n            res = self.wait()\n            self.assertEqual(res, OK)\n\n            server.close()\n            client.read_until(b\"\\r\\n\", lambda x: x)\n            # If _close_callback (self.stop) is not called,\n            # an AssertionError: Async operation timed out after 5 seconds\n            # will be raised.\n            res = self.wait()\n            self.assertTrue(res is None)\n        finally:\n            server.close()\n            client.close()\n\n    @skipIfNonUnix\n    def test_inline_read_error(self):\n        # An error on an inline read is raised without logging (on the\n        # assumption that it will eventually be noticed or logged further\n        # up the stack).\n        #\n        # This test is posix-only because windows os.close() doesn't work\n        # on socket FDs, but we can't close the socket object normally\n        # because we won't get the error we want if the socket knows\n        # it's closed.\n        server, client = self.make_iostream_pair()\n        try:\n            os.close(server.socket.fileno())\n            with self.assertRaises(socket.error):\n                server.read_bytes(1, lambda data: None)\n        finally:\n            server.close()\n            client.close()\n\n    def test_async_read_error_logging(self):\n        # Socket errors on asynchronous reads should be logged (but only\n        # once).\n        server, client = self.make_iostream_pair()\n        server.set_close_callback(self.stop)\n        try:\n            # Start a read that will be fullfilled asynchronously.\n            server.read_bytes(1, lambda data: None)\n            client.write(b'a')\n            # Stub out read_from_fd to make it fail.\n\n            def fake_read_from_fd():\n                os.close(server.socket.fileno())\n                server.__class__.read_from_fd(server)\n            server.read_from_fd = fake_read_from_fd\n            # This log message is from _handle_read (not read_from_fd).\n            with ExpectLog(gen_log, \"error on read\"):\n                self.wait()\n        finally:\n            server.close()\n            client.close()\n\n    def test_future_close_callback(self):\n        # Regression test for interaction between the Future read interfaces\n        # and IOStream._maybe_add_error_listener.\n        server, client = self.make_iostream_pair()\n        closed = [False]\n        def close_callback():\n            closed[0] = True\n            self.stop()\n        server.set_close_callback(close_callback)\n        try:\n            client.write(b'a')\n            future = server.read_bytes(1)\n            self.io_loop.add_future(future, self.stop)\n            self.assertEqual(self.wait().result(), b'a')\n            self.assertFalse(closed[0])\n            client.close()\n            self.wait()\n            self.assertTrue(closed[0])\n        finally:\n            server.close()\n            client.close()",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 151,
                                "end_lineno": 534,
                                "parent": null
                            }
                        }
                    ],
                    "deleted_entities": []
                }
            ]
        }
    ],
    "old_commit_hash": "e22cd67dc86ab0f3bce9af401c94dca63dcac9af^",
    "new_commit_hash": "e22cd67dc86ab0f3bce9af401c94dca63dcac9af",
    "commit_message": "Fix close_callback handling when the Future read interface is used.",
    "commit_date": "2014-02-23T15:30:47-05:00",
    "metadata": {}
}
{
    "repo_name": "tornado",
    "new_commit_hash": "e22cd67dc86ab0f3bce9af401c94dca63dcac9af",
    "test_file_codes": [
        "from __future__ import absolute_import, division, print_function, with_statement\nfrom tornado import netutil\nfrom tornado.ioloop import IOLoop\nfrom tornado.iostream import IOStream, SSLIOStream, PipeIOStream, StreamClosedError\nfrom tornado.httputil import HTTPHeaders\nfrom tornado.log import gen_log, app_log\nfrom tornado.netutil import ssl_wrap_socket\nfrom tornado.stack_context import NullContext\nfrom tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, bind_unused_port, ExpectLog, gen_test\nfrom tornado.test.util import unittest, skipIfNonUnix\nfrom tornado.web import RequestHandler, Application\nimport errno\nimport logging\nimport os\nimport platform\nimport socket\nimport ssl\nimport sys\n\n\nclass HelloHandler(RequestHandler):\n    def get(self):\n        self.write(\"Hello\")\n\n\nclass TestIOStreamWebMixin(object):\n    def _make_client_iostream(self):\n        raise NotImplementedError()\n\n    def get_app(self):\n        return Application([('/', HelloHandler)])\n\n    def test_connection_closed(self):\n        # When a server sends a response and then closes the connection,\n        # the client must be allowed to read the data before the IOStream\n        # closes itself.  Epoll reports closed connections with a separate\n        # EPOLLRDHUP event delivered at the same time as the read event,\n        # while kqueue reports them as a second read/write event with an EOF\n        # flag.\n        response = self.fetch(\"/\", headers={\"Connection\": \"close\"})\n        response.rethrow()\n\n    def test_read_until_close(self):\n        stream = self._make_client_iostream()\n        stream.connect(('localhost', self.get_http_port()), callback=self.stop)\n        self.wait()\n        stream.write(b\"GET / HTTP/1.0\\r\\n\\r\\n\")\n\n        stream.read_until_close(self.stop)\n        data = self.wait()\n        self.assertTrue(data.startswith(b\"HTTP/1.0 200\"))\n        self.assertTrue(data.endswith(b\"Hello\"))\n\n    def test_read_zero_bytes(self):\n        self.stream = self._make_client_iostream()\n        self.stream.connect((\"localhost\", self.get_http_port()),\n                            callback=self.stop)\n        self.wait()\n        self.stream.write(b\"GET / HTTP/1.0\\r\\n\\r\\n\")\n\n        # normal read\n        self.stream.read_bytes(9, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"HTTP/1.0 \")\n\n        # zero bytes\n        self.stream.read_bytes(0, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"\")\n\n        # another normal read\n        self.stream.read_bytes(3, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"200\")\n\n        self.stream.close()\n\n    def test_write_while_connecting(self):\n        stream = self._make_client_iostream()\n        connected = [False]\n\n        def connected_callback():\n            connected[0] = True\n            self.stop()\n        stream.connect((\"localhost\", self.get_http_port()),\n                       callback=connected_callback)\n        # unlike the previous tests, try to write before the connection\n        # is complete.\n        written = [False]\n\n        def write_callback():\n            written[0] = True\n            self.stop()\n        stream.write(b\"GET / HTTP/1.0\\r\\nConnection: close\\r\\n\\r\\n\",\n                     callback=write_callback)\n        self.assertTrue(not connected[0])\n        # by the time the write has flushed, the connection callback has\n        # also run\n        try:\n            self.wait(lambda: connected[0] and written[0])\n        finally:\n            logging.debug((connected, written))\n\n        stream.read_until_close(self.stop)\n        data = self.wait()\n        self.assertTrue(data.endswith(b\"Hello\"))\n\n        stream.close()\n\n    @gen_test\n    def test_future_interface(self):\n        \"\"\"Basic test of IOStream's ability to return Futures.\"\"\"\n        stream = self._make_client_iostream()\n        yield stream.connect((\"localhost\", self.get_http_port()))\n        yield stream.write(b\"GET / HTTP/1.0\\r\\n\\r\\n\")\n        first_line = yield stream.read_until(b\"\\r\\n\")\n        self.assertEqual(first_line, b\"HTTP/1.0 200 OK\\r\\n\")\n        # callback=None is equivalent to no callback.\n        header_data = yield stream.read_until(b\"\\r\\n\\r\\n\", callback=None)\n        headers = HTTPHeaders.parse(header_data.decode('latin1'))\n        content_length = int(headers['Content-Length'])\n        body = yield stream.read_bytes(content_length)\n        self.assertEqual(body, b'Hello')\n        stream.close()\n\n    @gen_test\n    def test_future_close_while_reading(self):\n        stream = self._make_client_iostream()\n        yield stream.connect((\"localhost\", self.get_http_port()))\n        yield stream.write(b\"GET / HTTP/1.0\\r\\n\\r\\n\")\n        with self.assertRaises(StreamClosedError):\n            yield stream.read_bytes(1024 * 1024)\n        stream.close()\n\n    @gen_test\n    def test_future_read_until_close(self):\n        # Ensure that the data comes through before the StreamClosedError.\n        stream = self._make_client_iostream()\n        yield stream.connect((\"localhost\", self.get_http_port()))\n        yield stream.write(b\"GET / HTTP/1.0\\r\\nConnection: close\\r\\n\\r\\n\")\n        yield stream.read_until(b\"\\r\\n\\r\\n\")\n        body = yield stream.read_until_close()\n        self.assertEqual(body, b\"Hello\")\n\n        # Nothing else to read; the error comes immediately without waiting\n        # for yield.\n        with self.assertRaises(StreamClosedError):\n            stream.read_bytes(1)\n\n\nclass TestIOStreamMixin(object):\n    def _make_server_iostream(self, connection, **kwargs):\n        raise NotImplementedError()\n\n    def _make_client_iostream(self, connection, **kwargs):\n        raise NotImplementedError()\n\n    def make_iostream_pair(self, **kwargs):\n        listener, port = bind_unused_port()\n        streams = [None, None]\n\n        def accept_callback(connection, address):\n            streams[0] = self._make_server_iostream(connection, **kwargs)\n            self.stop()\n\n        def connect_callback():\n            streams[1] = client_stream\n            self.stop()\n        netutil.add_accept_handler(listener, accept_callback,\n                                   io_loop=self.io_loop)\n        client_stream = self._make_client_iostream(socket.socket(), **kwargs)\n        client_stream.connect(('127.0.0.1', port),\n                              callback=connect_callback)\n        self.wait(condition=lambda: all(streams))\n        self.io_loop.remove_handler(listener.fileno())\n        listener.close()\n        return streams\n\n    def test_streaming_callback_with_data_in_buffer(self):\n        server, client = self.make_iostream_pair()\n        client.write(b\"abcd\\r\\nefgh\")\n        server.read_until(b\"\\r\\n\", self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"abcd\\r\\n\")\n\n        def closed_callback(chunk):\n            self.fail()\n        server.read_until_close(callback=closed_callback,\n                                streaming_callback=self.stop)\n        # self.io_loop.add_timeout(self.io_loop.time() + 0.01, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"efgh\")\n        server.close()\n        client.close()\n\n    def test_write_zero_bytes(self):\n        # Attempting to write zero bytes should run the callback without\n        # going into an infinite loop.\n        server, client = self.make_iostream_pair()\n        server.write(b'', callback=self.stop)\n        self.wait()\n        # As a side effect, the stream is now listening for connection\n        # close (if it wasn't already), but is not listening for writes\n        self.assertEqual(server._state, IOLoop.READ | IOLoop.ERROR)\n        server.close()\n        client.close()\n\n    def test_connection_refused(self):\n        # When a connection is refused, the connect callback should not\n        # be run.  (The kqueue IOLoop used to behave differently from the\n        # epoll IOLoop in this respect)\n        server_socket, port = bind_unused_port()\n        server_socket.close()\n        stream = IOStream(socket.socket(), self.io_loop)\n        self.connect_called = False\n\n        def connect_callback():\n            self.connect_called = True\n        stream.set_close_callback(self.stop)\n        # log messages vary by platform and ioloop implementation\n        with ExpectLog(gen_log, \".*\", required=False):\n            stream.connect((\"localhost\", port), connect_callback)\n            self.wait()\n        self.assertFalse(self.connect_called)\n        self.assertTrue(isinstance(stream.error, socket.error), stream.error)\n        if sys.platform != 'cygwin':\n            # cygwin's errnos don't match those used on native windows python\n            self.assertEqual(stream.error.args[0], errno.ECONNREFUSED)\n\n    def test_gaierror(self):\n        # Test that IOStream sets its exc_info on getaddrinfo error\n        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)\n        stream = IOStream(s, io_loop=self.io_loop)\n        stream.set_close_callback(self.stop)\n        # To reliably generate a gaierror we use a malformed domain name\n        # instead of a name that's simply unlikely to exist (since\n        # opendns and some ISPs return bogus addresses for nonexistent\n        # domains instead of the proper error codes).\n        with ExpectLog(gen_log, \"Connect error\"):\n            stream.connect(('an invalid domain', 54321))\n            self.assertTrue(isinstance(stream.error, socket.gaierror), stream.error)\n\n    def test_read_callback_error(self):\n        # Test that IOStream sets its exc_info when a read callback throws\n        server, client = self.make_iostream_pair()\n        try:\n            server.set_close_callback(self.stop)\n            with ExpectLog(\n                app_log, \"(Uncaught exception|Exception in callback)\"\n            ):\n                # Clear ExceptionStackContext so IOStream catches error\n                with NullContext():\n                    server.read_bytes(1, callback=lambda data: 1 / 0)\n                client.write(b\"1\")\n                self.wait()\n            self.assertTrue(isinstance(server.error, ZeroDivisionError))\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_callback(self):\n        server, client = self.make_iostream_pair()\n        try:\n            chunks = []\n            final_called = []\n\n            def streaming_callback(data):\n                chunks.append(data)\n                self.stop()\n\n            def final_callback(data):\n                self.assertFalse(data)\n                final_called.append(True)\n                self.stop()\n            server.read_bytes(6, callback=final_callback,\n                              streaming_callback=streaming_callback)\n            client.write(b\"1234\")\n            self.wait(condition=lambda: chunks)\n            client.write(b\"5678\")\n            self.wait(condition=lambda: final_called)\n            self.assertEqual(chunks, [b\"1234\", b\"56\"])\n\n            # the rest of the last chunk is still in the buffer\n            server.read_bytes(2, callback=self.stop)\n            data = self.wait()\n            self.assertEqual(data, b\"78\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_until_close(self):\n        server, client = self.make_iostream_pair()\n        try:\n            chunks = []\n            closed = [False]\n\n            def streaming_callback(data):\n                chunks.append(data)\n                self.stop()\n            def close_callback(data):\n                assert not data, data\n                closed[0] = True\n                self.stop()\n            client.read_until_close(callback=close_callback,\n                                    streaming_callback=streaming_callback)\n            server.write(b\"1234\")\n            self.wait(condition=lambda: len(chunks) == 1)\n            server.write(b\"5678\", self.stop)\n            self.wait()\n            server.close()\n            self.wait(condition=lambda: closed[0])\n            self.assertEqual(chunks, [b\"1234\", b\"5678\"])\n        finally:\n            server.close()\n            client.close()\n\n    def test_delayed_close_callback(self):\n        # The scenario:  Server closes the connection while there is a pending\n        # read that can be served out of buffered data.  The client does not\n        # run the close_callback as soon as it detects the close, but rather\n        # defers it until after the buffered read has finished.\n        server, client = self.make_iostream_pair()\n        try:\n            client.set_close_callback(self.stop)\n            server.write(b\"12\")\n            chunks = []\n\n            def callback1(data):\n                chunks.append(data)\n                client.read_bytes(1, callback2)\n                server.close()\n\n            def callback2(data):\n                chunks.append(data)\n            client.read_bytes(1, callback1)\n            self.wait()  # stopped by close_callback\n            self.assertEqual(chunks, [b\"1\", b\"2\"])\n        finally:\n            server.close()\n            client.close()\n\n    def test_future_delayed_close_callback(self):\n        # Same as test_delayed_close_callback, but with the future interface.\n        server, client = self.make_iostream_pair()\n        # We can't call make_iostream_pair inside a gen_test function\n        # because the ioloop is not reentrant.\n        @gen_test\n        def f(self):\n            server.write(b\"12\")\n            chunks = []\n            chunks.append((yield client.read_bytes(1)))\n            server.close()\n            chunks.append((yield client.read_bytes(1)))\n            self.assertEqual(chunks, [b\"1\", b\"2\"])\n        try:\n            f(self)\n        finally:\n            server.close()\n            client.close()\n\n    def test_close_buffered_data(self):\n        # Similar to the previous test, but with data stored in the OS's\n        # socket buffers instead of the IOStream's read buffer.  Out-of-band\n        # close notifications must be delayed until all data has been\n        # drained into the IOStream buffer. (epoll used to use out-of-band\n        # close events with EPOLLRDHUP, but no longer)\n        #\n        # This depends on the read_chunk_size being smaller than the\n        # OS socket buffer, so make it small.\n        server, client = self.make_iostream_pair(read_chunk_size=256)\n        try:\n            server.write(b\"A\" * 512)\n            client.read_bytes(256, self.stop)\n            data = self.wait()\n            self.assertEqual(b\"A\" * 256, data)\n            server.close()\n            # Allow the close to propagate to the client side of the\n            # connection.  Using add_callback instead of add_timeout\n            # doesn't seem to work, even with multiple iterations\n            self.io_loop.add_timeout(self.io_loop.time() + 0.01, self.stop)\n            self.wait()\n            client.read_bytes(256, self.stop)\n            data = self.wait()\n            self.assertEqual(b\"A\" * 256, data)\n        finally:\n            server.close()\n            client.close()\n\n    def test_read_until_close_after_close(self):\n        # Similar to test_delayed_close_callback, but read_until_close takes\n        # a separate code path so test it separately.\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(b\"1234\")\n            server.close()\n            self.wait()\n            client.read_until_close(self.stop)\n            data = self.wait()\n            self.assertEqual(data, b\"1234\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_streaming_read_until_close_after_close(self):\n        # Same as the preceding test but with a streaming_callback.\n        # All data should go through the streaming callback,\n        # and the final read callback just gets an empty string.\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(b\"1234\")\n            server.close()\n            self.wait()\n            streaming_data = []\n            client.read_until_close(self.stop,\n                                    streaming_callback=streaming_data.append)\n            data = self.wait()\n            self.assertEqual(b'', data)\n            self.assertEqual(b''.join(streaming_data), b\"1234\")\n        finally:\n            server.close()\n            client.close()\n\n    def test_large_read_until(self):\n        # Performance test: read_until used to have a quadratic component\n        # so a read_until of 4MB would take 8 seconds; now it takes 0.25\n        # seconds.\n        server, client = self.make_iostream_pair()\n        try:\n            # This test fails on pypy with ssl.  I think it's because\n            # pypy's gc defeats moves objects, breaking the\n            # \"frozen write buffer\" assumption.\n            if (isinstance(server, SSLIOStream) and\n                    platform.python_implementation() == 'PyPy'):\n                raise unittest.SkipTest(\n                    \"pypy gc causes problems with openssl\")\n            NUM_KB = 4096\n            for i in range(NUM_KB):\n                client.write(b\"A\" * 1024)\n            client.write(b\"\\r\\n\")\n            server.read_until(b\"\\r\\n\", self.stop)\n            data = self.wait()\n            self.assertEqual(len(data), NUM_KB * 1024 + 2)\n        finally:\n            server.close()\n            client.close()\n\n    def test_close_callback_with_pending_read(self):\n        # Regression test for a bug that was introduced in 2.3\n        # where the IOStream._close_callback would never be called\n        # if there were pending reads.\n        OK = b\"OK\\r\\n\"\n        server, client = self.make_iostream_pair()\n        client.set_close_callback(self.stop)\n        try:\n            server.write(OK)\n            client.read_until(b\"\\r\\n\", self.stop)\n            res = self.wait()\n            self.assertEqual(res, OK)\n\n            server.close()\n            client.read_until(b\"\\r\\n\", lambda x: x)\n            # If _close_callback (self.stop) is not called,\n            # an AssertionError: Async operation timed out after 5 seconds\n            # will be raised.\n            res = self.wait()\n            self.assertTrue(res is None)\n        finally:\n            server.close()\n            client.close()\n\n    @skipIfNonUnix\n    def test_inline_read_error(self):\n        # An error on an inline read is raised without logging (on the\n        # assumption that it will eventually be noticed or logged further\n        # up the stack).\n        #\n        # This test is posix-only because windows os.close() doesn't work\n        # on socket FDs, but we can't close the socket object normally\n        # because we won't get the error we want if the socket knows\n        # it's closed.\n        server, client = self.make_iostream_pair()\n        try:\n            os.close(server.socket.fileno())\n            with self.assertRaises(socket.error):\n                server.read_bytes(1, lambda data: None)\n        finally:\n            server.close()\n            client.close()\n\n    def test_async_read_error_logging(self):\n        # Socket errors on asynchronous reads should be logged (but only\n        # once).\n        server, client = self.make_iostream_pair()\n        server.set_close_callback(self.stop)\n        try:\n            # Start a read that will be fullfilled asynchronously.\n            server.read_bytes(1, lambda data: None)\n            client.write(b'a')\n            # Stub out read_from_fd to make it fail.\n\n            def fake_read_from_fd():\n                os.close(server.socket.fileno())\n                server.__class__.read_from_fd(server)\n            server.read_from_fd = fake_read_from_fd\n            # This log message is from _handle_read (not read_from_fd).\n            with ExpectLog(gen_log, \"error on read\"):\n                self.wait()\n        finally:\n            server.close()\n            client.close()\n\n    def test_future_close_callback(self):\n        # Regression test for interaction between the Future read interfaces\n        # and IOStream._maybe_add_error_listener.\n        server, client = self.make_iostream_pair()\n        closed = [False]\n        def close_callback():\n            closed[0] = True\n            self.stop()\n        server.set_close_callback(close_callback)\n        try:\n            client.write(b'a')\n            future = server.read_bytes(1)\n            self.io_loop.add_future(future, self.stop)\n            self.assertEqual(self.wait().result(), b'a')\n            self.assertFalse(closed[0])\n            client.close()\n            self.wait()\n            self.assertTrue(closed[0])\n        finally:\n            server.close()\n            client.close()\n\n\nclass TestIOStreamWebHTTP(TestIOStreamWebMixin, AsyncHTTPTestCase):\n    def _make_client_iostream(self):\n        return IOStream(socket.socket(), io_loop=self.io_loop)\n\n\nclass TestIOStreamWebHTTPS(TestIOStreamWebMixin, AsyncHTTPSTestCase):\n    def _make_client_iostream(self):\n        return SSLIOStream(socket.socket(), io_loop=self.io_loop)\n\n\nclass TestIOStream(TestIOStreamMixin, AsyncTestCase):\n    def _make_server_iostream(self, connection, **kwargs):\n        return IOStream(connection, **kwargs)\n\n    def _make_client_iostream(self, connection, **kwargs):\n        return IOStream(connection, **kwargs)\n\n\nclass TestIOStreamSSL(TestIOStreamMixin, AsyncTestCase):\n    def _make_server_iostream(self, connection, **kwargs):\n        ssl_options = dict(\n            certfile=os.path.join(os.path.dirname(__file__), 'test.crt'),\n            keyfile=os.path.join(os.path.dirname(__file__), 'test.key'),\n        )\n        connection = ssl.wrap_socket(connection,\n                                     server_side=True,\n                                     do_handshake_on_connect=False,\n                                     **ssl_options)\n        return SSLIOStream(connection, io_loop=self.io_loop, **kwargs)\n\n    def _make_client_iostream(self, connection, **kwargs):\n        return SSLIOStream(connection, io_loop=self.io_loop, **kwargs)\n\n\n# This will run some tests that are basically redundant but it's the\n# simplest way to make sure that it works to pass an SSLContext\n# instead of an ssl_options dict to the SSLIOStream constructor.\n@unittest.skipIf(not hasattr(ssl, 'SSLContext'), 'ssl.SSLContext not present')\nclass TestIOStreamSSLContext(TestIOStreamMixin, AsyncTestCase):\n    def _make_server_iostream(self, connection, **kwargs):\n        context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)\n        context.load_cert_chain(\n            os.path.join(os.path.dirname(__file__), 'test.crt'),\n            os.path.join(os.path.dirname(__file__), 'test.key'))\n        connection = ssl_wrap_socket(connection, context,\n                                     server_side=True,\n                                     do_handshake_on_connect=False)\n        return SSLIOStream(connection, io_loop=self.io_loop, **kwargs)\n\n    def _make_client_iostream(self, connection, **kwargs):\n        context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)\n        return SSLIOStream(connection, io_loop=self.io_loop,\n                           ssl_options=context, **kwargs)\n\n\n@skipIfNonUnix\nclass TestPipeIOStream(AsyncTestCase):\n    def test_pipe_iostream(self):\n        r, w = os.pipe()\n\n        rs = PipeIOStream(r, io_loop=self.io_loop)\n        ws = PipeIOStream(w, io_loop=self.io_loop)\n\n        ws.write(b\"hel\")\n        ws.write(b\"lo world\")\n\n        rs.read_until(b' ', callback=self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"hello \")\n\n        rs.read_bytes(3, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"wor\")\n\n        ws.close()\n\n        rs.read_until_close(self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"ld\")\n\n        rs.close()\n\n    def test_pipe_iostream_big_write(self):\n        r, w = os.pipe()\n\n        rs = PipeIOStream(r, io_loop=self.io_loop)\n        ws = PipeIOStream(w, io_loop=self.io_loop)\n\n        NUM_BYTES = 1048576\n\n        # Write 1MB of data, which should fill the buffer\n        ws.write(b\"1\" * NUM_BYTES)\n\n        rs.read_bytes(NUM_BYTES, self.stop)\n        data = self.wait()\n        self.assertEqual(data, b\"1\" * NUM_BYTES)\n\n        ws.close()\n        rs.close()\n",
        "#!/usr/bin/env python\nimport unittest\nimport sys\nimport time\nimport traceback\nimport platform\nimport os\n\n\nclass PytestLikeResult(unittest.TestResult):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self.start_time = None\n        # Store (test, outcome, info) for each test:\n        #   outcome ∈ { \"passed\", \"failed\", \"error\", \"skipped\" }\n        #   info can hold the exception or skip reason, etc.\n        self.results = []\n\n    def startTestRun(self):\n        \"\"\"Called once before all tests.\"\"\"\n        self.start_time = time.time()\n        # Print a header similar to pytest\n        print(\"=\" * 29 + \" test session starts \" + \"=\" * 29)\n        # You can customize the platform/versions/paths as you like:\n        print(\n            f\"platform {platform.system().lower()} -- Python {platform.python_version()}\"\n        )\n        print(f\"rootdir: {os.path.abspath(os.curdir)}\")\n\n    def stopTestRun(self):\n        \"\"\"Called once after all tests are done.\"\"\"\n        elapsed = time.time() - self.start_time\n        print()  # blank line after final dot\n\n        # Summarize\n        ntests = len(self.results)\n        print(f\"collected {ntests} items\")\n\n        # Show details of failures/errors\n        failures = [r for r in self.results if r[1] == \"failed\"]\n        errors = [r for r in self.results if r[1] == \"error\"]\n\n        if failures:\n            print(\"\\n\" + \"=\" * 35 + \" FAILURES \" + \"=\" * 35)\n            for test, outcome, err_info in failures:\n                test = test.split(\"::\")\n                if len(test) == 3:\n                    test = f\"{test[1]}.{test[2]}\"\n                else:\n                    test = f\"{test[1]}\"\n                print(f\"__________ {test} __________\")\n                self._print_traceback(err_info)\n        if errors:\n            print(\"\\n\" + \"=\" * 35 + \" ERRORS \" + \"=\" * 37)\n            for test, outcome, err_info in errors:\n                test = test.split(\"::\")\n                if len(test) == 3:\n                    test = f\"{test[1]}.{test[2]}\"\n                else:\n                    test = f\"{test[1]}\"\n                print(f\"__________ {test} __________\")\n                self._print_traceback(err_info)\n\n        # Optional short summary lines for passes/fails/skips\n        print(\"\\n==================== short test summary info ====================\")\n        for test, outcome, info in self.results:\n            if outcome in (\"passed\", \"failed\", \"error\", \"skipped\"):\n                print(f\"{outcome.upper()} {test}\")\n\n        # Final one-line summary: “1 failed, 1 errors, 10 passed in 2.04s”\n        passed_count = sum(1 for r in self.results if r[1] == \"passed\")\n        failed_count = len(failures)\n        error_count = len(errors)\n        skipped_count = sum(1 for r in self.results if r[1] == \"skipped\")\n\n        summary_bits = []\n        if failed_count:\n            summary_bits.append(f\"{failed_count} failed\")\n        if error_count:\n            summary_bits.append(f\"{error_count} error{'s' if error_count != 1 else ''}\")\n        if passed_count:\n            summary_bits.append(f\"{passed_count} passed\")\n        if skipped_count:\n            summary_bits.append(f\"{skipped_count} skipped\")\n\n        summary_str = \", \".join(summary_bits) if summary_bits else \"no tests run\"\n        print(\n            f\"=================== {summary_str} in {elapsed:.2f}s ===================\"\n        )\n\n    def startTest(self, test):\n        \"\"\"Called right before each test method.\"\"\"\n        super().startTest(test)\n        # Print a dot or some indicator\n        print(\".\", end=\"\", flush=True)\n\n    def addSuccess(self, test):\n        super().addSuccess(test)\n        self.results.append((self._test_id(test), \"passed\", None))\n\n    def addFailure(self, test, err):\n        super().addFailure(test, err)\n        self.results.append((self._test_id(test), \"failed\", err))\n\n    def addError(self, test, err):\n        super().addError(test, err)\n        self.results.append((self._test_id(test), \"error\", err))\n\n    def addSkip(self, test, reason):\n        super().addSkip(test, reason)\n        self.results.append((self._test_id(test), \"skipped\", reason))\n\n    def _print_traceback(self, err_info):\n        \"\"\"Helper to print the traceback like pytest does.\"\"\"\n        if isinstance(err_info, tuple) and len(err_info) == 3:\n            exc_type, exc_value, tb = err_info\n            traceback.print_exception(exc_type, exc_value, tb, file=sys.stdout)\n        else:\n            print(str(err_info))\n\n    def _test_id(self, test):\n        try:\n            return f\"{test.__class__.__module__}::{test.__class__.__name__}::{test._testMethodName}\"\n        except AttributeError:\n            # Fallback for _ErrorHolder objects\n            return f\"{test.__class__.__module__}::{test.__class__.__name__}\"\n\n\nclass PytestLikeRunner(unittest.TextTestRunner):\n    \"\"\"A custom TextTestRunner that uses the PytestLikeResult.\"\"\"\n\n    resultclass = PytestLikeResult\n\n    def run(self, test):\n        result = self._makeResult()\n        # Overriding run to ensure we call startTestRun/stopTestRun\n        result.startTestRun()\n        test(result)\n        result.stopTestRun()\n        return result\n\n    def tearDown(self):\n        # Reset signal handlers\n        from twisted.internet import reactor\n\n        reactor.removeAll()\n        reactor.stop()\n        super().tearDown()\n\n\ndef main():\n    loader = unittest.TestLoader()\n    suite = loader.discover(\".\", pattern=\"test_*.py\")  # discover tests in r2e_tests/\n    runner = PytestLikeRunner(verbosity=0)\n    result = runner.run(suite)\n    # Exit with code 0 if all tests passed/skipped, 1 if there were fails/errors\n    sys.exit(not result.wasSuccessful())\n\n\nif __name__ == \"__main__\":\n    main()\n"
    ],
    "test_file_names": [
        "test_1.py",
        "tornado_unittest_runner.py"
    ],
    "setup_res_code": 0,
    "setup_res_stdout": "",
    "setup_res_stderr": "Using CPython 3.9.21\nCreating virtual environment at: .venv\nActivate with: source .venv/bin/activate\nResolved 1 package in 822ms\nPrepared 1 package in 1.08s\nInstalled 1 package in 0.68ms\n + tornado==3.3.dev1 (from file:///home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af)\nResolved 29 packages in 17ms\nInstalled 29 packages in 164ms\n + attrs==24.3.0\n + automat==24.8.1\n + cachetools==5.5.0\n + cffi==1.17.1\n + chardet==5.2.0\n + colorama==0.4.6\n + constantly==23.10.4\n + distlib==0.3.9\n + exceptiongroup==1.2.2\n + filelock==3.16.1\n + hyperlink==21.0.0\n + idna==3.10\n + incremental==24.7.2\n + iniconfig==2.0.0\n + packaging==24.2\n + platformdirs==4.3.6\n + pluggy==1.5.0\n + pycares==4.5.0\n + pycparser==2.22\n + pycurl==7.45.4\n + pyproject-api==1.8.0\n + pytest==8.3.4\n + setuptools==75.6.0\n + tomli==2.2.1\n + tox==4.23.2\n + twisted==24.11.0\n + typing-extensions==4.12.2\n + virtualenv==20.28.0\n + zope-interface==7.2\n",
    "new_commit_res_code": 1,
    "new_commit_res_stdout": "============================= test session starts =============================\nplatform linux -- Python 3.9.21\nrootdir: /home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af\n...................................................................\ncollected 70 items\n\n=================================== ERRORS =====================================\n__________ TestIOStreamSSL.test_async_read_error_logging __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 495, in test_async_read_error_logging\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_close_buffered_data __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 370, in test_close_buffered_data\n    server, client = self.make_iostream_pair(read_chunk_size=256)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_close_callback_with_pending_read __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 454, in test_close_callback_with_pending_read\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_delayed_close_callback __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 322, in test_delayed_close_callback\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_future_close_callback __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 517, in test_future_close_callback\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_future_delayed_close_callback __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 344, in test_future_delayed_close_callback\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_inline_read_error __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 483, in test_inline_read_error\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_large_read_until __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 429, in test_large_read_until\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_read_callback_error __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 245, in test_read_callback_error\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_read_until_close_after_close __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 392, in test_read_until_close_after_close\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_streaming_callback __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 262, in test_streaming_callback\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_streaming_callback_with_data_in_buffer __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 180, in test_streaming_callback_with_data_in_buffer\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_streaming_read_until_close_after_close __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 409, in test_streaming_read_until_close_after_close\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_streaming_until_close __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 292, in test_streaming_until_close\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_write_zero_bytes __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 199, in test_write_zero_bytes\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_async_read_error_logging __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 495, in test_async_read_error_logging\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_close_buffered_data __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 370, in test_close_buffered_data\n    server, client = self.make_iostream_pair(read_chunk_size=256)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_close_callback_with_pending_read __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 454, in test_close_callback_with_pending_read\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_delayed_close_callback __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 322, in test_delayed_close_callback\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_future_close_callback __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 517, in test_future_close_callback\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_future_delayed_close_callback __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 344, in test_future_delayed_close_callback\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_inline_read_error __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 483, in test_inline_read_error\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_large_read_until __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 429, in test_large_read_until\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_read_callback_error __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 245, in test_read_callback_error\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_read_until_close_after_close __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 392, in test_read_until_close_after_close\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_streaming_callback __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 262, in test_streaming_callback\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_streaming_callback_with_data_in_buffer __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 180, in test_streaming_callback_with_data_in_buffer\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_streaming_read_until_close_after_close __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 409, in test_streaming_read_until_close_after_close\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_streaming_until_close __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 292, in test_streaming_until_close\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_write_zero_bytes __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 199, in test_write_zero_bytes\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamWebHTTPS.test_connection_closed __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 40, in test_connection_closed\n    response = self.fetch(\"/\", headers={\"Connection\": \"close\"})\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 366, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/tcpserver.py\", line 214, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 405, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 386, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ TestIOStreamWebHTTPS.test_future_close_while_reading __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 486, in post_coroutine\n    self._test_generator.throw(e)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 130, in test_future_close_while_reading\n    yield stream.write(b\"GET / HTTP/1.0\\r\\n\\r\\n\")\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 480, in post_coroutine\n    return self.io_loop.run_sync(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/ioloop.py\", line 407, in run_sync\n    raise TimeoutError('Operation timed out after %s seconds' % timeout)\ntornado.ioloop.TimeoutError: Operation timed out after 5 seconds\n__________ TestIOStreamWebHTTPS.test_future_close_while_reading __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 595, in run\n    self._callTearDown()\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 553, in _callTearDown\n    self.tearDown()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 394, in tearDown\n    super(AsyncHTTPTestCase, self).tearDown()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 223, in tearDown\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/tcpserver.py\", line 214, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 405, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 386, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ TestIOStreamWebHTTPS.test_future_interface __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 486, in post_coroutine\n    self._test_generator.throw(e)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 115, in test_future_interface\n    yield stream.write(b\"GET / HTTP/1.0\\r\\n\\r\\n\")\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 480, in post_coroutine\n    return self.io_loop.run_sync(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/ioloop.py\", line 407, in run_sync\n    raise TimeoutError('Operation timed out after %s seconds' % timeout)\ntornado.ioloop.TimeoutError: Operation timed out after 5 seconds\n__________ TestIOStreamWebHTTPS.test_future_interface __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 595, in run\n    self._callTearDown()\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 553, in _callTearDown\n    self.tearDown()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 394, in tearDown\n    super(AsyncHTTPTestCase, self).tearDown()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 223, in tearDown\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/tcpserver.py\", line 214, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 405, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 386, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ TestIOStreamWebHTTPS.test_future_read_until_close __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 486, in post_coroutine\n    self._test_generator.throw(e)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 140, in test_future_read_until_close\n    yield stream.write(b\"GET / HTTP/1.0\\r\\nConnection: close\\r\\n\\r\\n\")\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 480, in post_coroutine\n    return self.io_loop.run_sync(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/ioloop.py\", line 407, in run_sync\n    raise TimeoutError('Operation timed out after %s seconds' % timeout)\ntornado.ioloop.TimeoutError: Operation timed out after 5 seconds\n__________ TestIOStreamWebHTTPS.test_future_read_until_close __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 595, in run\n    self._callTearDown()\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 553, in _callTearDown\n    self.tearDown()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 394, in tearDown\n    super(AsyncHTTPTestCase, self).tearDown()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 223, in tearDown\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/tcpserver.py\", line 214, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 405, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 386, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ TestIOStreamWebHTTPS.test_read_until_close __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 46, in test_read_until_close\n    self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/tcpserver.py\", line 214, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 405, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 386, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ TestIOStreamWebHTTPS.test_read_zero_bytes __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 58, in test_read_zero_bytes\n    self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/tcpserver.py\", line 214, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 405, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 386, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ TestIOStreamWebHTTPS.test_write_while_connecting __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 100, in test_write_while_connecting\n    self.wait(lambda: connected[0] and written[0])\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/tcpserver.py\", line 214, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 405, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 386, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n\n==================== short test summary info ====================\nPASSED r2e_tests.test_1::TestIOStream::test_async_read_error_logging\nPASSED r2e_tests.test_1::TestIOStream::test_close_buffered_data\nPASSED r2e_tests.test_1::TestIOStream::test_close_callback_with_pending_read\nPASSED r2e_tests.test_1::TestIOStream::test_connection_refused\nPASSED r2e_tests.test_1::TestIOStream::test_delayed_close_callback\nPASSED r2e_tests.test_1::TestIOStream::test_future_close_callback\nPASSED r2e_tests.test_1::TestIOStream::test_future_delayed_close_callback\nPASSED r2e_tests.test_1::TestIOStream::test_gaierror\nPASSED r2e_tests.test_1::TestIOStream::test_inline_read_error\nPASSED r2e_tests.test_1::TestIOStream::test_large_read_until\nPASSED r2e_tests.test_1::TestIOStream::test_read_callback_error\nPASSED r2e_tests.test_1::TestIOStream::test_read_until_close_after_close\nPASSED r2e_tests.test_1::TestIOStream::test_streaming_callback\nPASSED r2e_tests.test_1::TestIOStream::test_streaming_callback_with_data_in_buffer\nPASSED r2e_tests.test_1::TestIOStream::test_streaming_read_until_close_after_close\nPASSED r2e_tests.test_1::TestIOStream::test_streaming_until_close\nPASSED r2e_tests.test_1::TestIOStream::test_write_zero_bytes\nERROR r2e_tests.test_1::TestIOStreamSSL::test_async_read_error_logging\nERROR r2e_tests.test_1::TestIOStreamSSL::test_close_buffered_data\nERROR r2e_tests.test_1::TestIOStreamSSL::test_close_callback_with_pending_read\nPASSED r2e_tests.test_1::TestIOStreamSSL::test_connection_refused\nERROR r2e_tests.test_1::TestIOStreamSSL::test_delayed_close_callback\nERROR r2e_tests.test_1::TestIOStreamSSL::test_future_close_callback\nERROR r2e_tests.test_1::TestIOStreamSSL::test_future_delayed_close_callback\nPASSED r2e_tests.test_1::TestIOStreamSSL::test_gaierror\nERROR r2e_tests.test_1::TestIOStreamSSL::test_inline_read_error\nERROR r2e_tests.test_1::TestIOStreamSSL::test_large_read_until\nERROR r2e_tests.test_1::TestIOStreamSSL::test_read_callback_error\nERROR r2e_tests.test_1::TestIOStreamSSL::test_read_until_close_after_close\nERROR r2e_tests.test_1::TestIOStreamSSL::test_streaming_callback\nERROR r2e_tests.test_1::TestIOStreamSSL::test_streaming_callback_with_data_in_buffer\nERROR r2e_tests.test_1::TestIOStreamSSL::test_streaming_read_until_close_after_close\nERROR r2e_tests.test_1::TestIOStreamSSL::test_streaming_until_close\nERROR r2e_tests.test_1::TestIOStreamSSL::test_write_zero_bytes\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_async_read_error_logging\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_close_buffered_data\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_close_callback_with_pending_read\nPASSED r2e_tests.test_1::TestIOStreamSSLContext::test_connection_refused\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_delayed_close_callback\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_future_close_callback\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_future_delayed_close_callback\nPASSED r2e_tests.test_1::TestIOStreamSSLContext::test_gaierror\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_inline_read_error\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_large_read_until\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_read_callback_error\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_read_until_close_after_close\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_streaming_callback\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_streaming_callback_with_data_in_buffer\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_streaming_read_until_close_after_close\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_streaming_until_close\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_write_zero_bytes\nPASSED r2e_tests.test_1::TestIOStreamWebHTTP::test_connection_closed\nPASSED r2e_tests.test_1::TestIOStreamWebHTTP::test_future_close_while_reading\nPASSED r2e_tests.test_1::TestIOStreamWebHTTP::test_future_interface\nPASSED r2e_tests.test_1::TestIOStreamWebHTTP::test_future_read_until_close\nPASSED r2e_tests.test_1::TestIOStreamWebHTTP::test_read_until_close\nPASSED r2e_tests.test_1::TestIOStreamWebHTTP::test_read_zero_bytes\nPASSED r2e_tests.test_1::TestIOStreamWebHTTP::test_write_while_connecting\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_connection_closed\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_future_close_while_reading\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_future_close_while_reading\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_future_interface\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_future_interface\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_future_read_until_close\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_future_read_until_close\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_read_until_close\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_read_zero_bytes\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_write_while_connecting\nPASSED r2e_tests.test_1::TestPipeIOStream::test_pipe_iostream\nPASSED r2e_tests.test_1::TestPipeIOStream::test_pipe_iostream_big_write\n=================== 40 errors, 30 passed in 15.19s ===================\n",
    "new_commit_res_stderr": "",
    "old_commit_res_code": 1,
    "old_commit_res_stdout": "============================= test session starts =============================\nplatform linux -- Python 3.9.21\nrootdir: /home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af\n...................................................................\ncollected 70 items\n\n=================================== FAILURES ===================================\n__________ TestIOStream.test_future_close_callback __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 530, in test_future_close_callback\n    self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 287, in timeout_func\n    raise self.failureException(\nAssertionError: Async operation timed out after 5 seconds\n\n=================================== ERRORS =====================================\n__________ TestIOStreamSSL.test_async_read_error_logging __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 495, in test_async_read_error_logging\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_close_buffered_data __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 370, in test_close_buffered_data\n    server, client = self.make_iostream_pair(read_chunk_size=256)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_close_callback_with_pending_read __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 454, in test_close_callback_with_pending_read\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_delayed_close_callback __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 322, in test_delayed_close_callback\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_future_close_callback __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 517, in test_future_close_callback\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_future_delayed_close_callback __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 344, in test_future_delayed_close_callback\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_inline_read_error __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 483, in test_inline_read_error\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_large_read_until __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 429, in test_large_read_until\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_read_callback_error __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 245, in test_read_callback_error\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_read_until_close_after_close __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 392, in test_read_until_close_after_close\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_streaming_callback __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 262, in test_streaming_callback\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_streaming_callback_with_data_in_buffer __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 180, in test_streaming_callback_with_data_in_buffer\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_streaming_read_until_close_after_close __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 409, in test_streaming_read_until_close_after_close\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_streaming_until_close __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 292, in test_streaming_until_close\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSL.test_write_zero_bytes __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 199, in test_write_zero_bytes\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 561, in _make_server_iostream\n    connection = ssl.wrap_socket(connection,\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/ssl.py\", line 1436, in wrap_socket\n    context.load_cert_chain(certfile, keyfile)\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_async_read_error_logging __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 495, in test_async_read_error_logging\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_close_buffered_data __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 370, in test_close_buffered_data\n    server, client = self.make_iostream_pair(read_chunk_size=256)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_close_callback_with_pending_read __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 454, in test_close_callback_with_pending_read\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_delayed_close_callback __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 322, in test_delayed_close_callback\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_future_close_callback __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 517, in test_future_close_callback\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_future_delayed_close_callback __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 344, in test_future_delayed_close_callback\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_inline_read_error __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 483, in test_inline_read_error\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_large_read_until __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 429, in test_large_read_until\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_read_callback_error __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 245, in test_read_callback_error\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_read_until_close_after_close __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 392, in test_read_until_close_after_close\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_streaming_callback __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 262, in test_streaming_callback\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_streaming_callback_with_data_in_buffer __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 180, in test_streaming_callback_with_data_in_buffer\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_streaming_read_until_close_after_close __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 409, in test_streaming_read_until_close_after_close\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_streaming_until_close __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 292, in test_streaming_until_close\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamSSLContext.test_write_zero_bytes __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 199, in test_write_zero_bytes\n    server, client = self.make_iostream_pair()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 174, in make_iostream_pair\n    self.wait(condition=lambda: all(streams))\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 163, in accept_callback\n    streams[0] = self._make_server_iostream(connection, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 578, in _make_server_iostream\n    context.load_cert_chain(\nFileNotFoundError: [Errno 2] No such file or directory\n__________ TestIOStreamWebHTTPS.test_connection_closed __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 40, in test_connection_closed\n    response = self.fetch(\"/\", headers={\"Connection\": \"close\"})\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 366, in fetch\n    return self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/tcpserver.py\", line 214, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 405, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 386, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ TestIOStreamWebHTTPS.test_future_close_while_reading __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 486, in post_coroutine\n    self._test_generator.throw(e)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 130, in test_future_close_while_reading\n    yield stream.write(b\"GET / HTTP/1.0\\r\\n\\r\\n\")\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 480, in post_coroutine\n    return self.io_loop.run_sync(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/ioloop.py\", line 407, in run_sync\n    raise TimeoutError('Operation timed out after %s seconds' % timeout)\ntornado.ioloop.TimeoutError: Operation timed out after 5 seconds\n__________ TestIOStreamWebHTTPS.test_future_close_while_reading __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 595, in run\n    self._callTearDown()\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 553, in _callTearDown\n    self.tearDown()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 394, in tearDown\n    super(AsyncHTTPTestCase, self).tearDown()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 223, in tearDown\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/tcpserver.py\", line 214, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 405, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 386, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ TestIOStreamWebHTTPS.test_future_interface __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 486, in post_coroutine\n    self._test_generator.throw(e)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 115, in test_future_interface\n    yield stream.write(b\"GET / HTTP/1.0\\r\\n\\r\\n\")\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 480, in post_coroutine\n    return self.io_loop.run_sync(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/ioloop.py\", line 407, in run_sync\n    raise TimeoutError('Operation timed out after %s seconds' % timeout)\ntornado.ioloop.TimeoutError: Operation timed out after 5 seconds\n__________ TestIOStreamWebHTTPS.test_future_interface __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 595, in run\n    self._callTearDown()\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 553, in _callTearDown\n    self.tearDown()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 394, in tearDown\n    super(AsyncHTTPTestCase, self).tearDown()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 223, in tearDown\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/tcpserver.py\", line 214, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 405, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 386, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ TestIOStreamWebHTTPS.test_future_read_until_close __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 486, in post_coroutine\n    self._test_generator.throw(e)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 140, in test_future_read_until_close\n    yield stream.write(b\"GET / HTTP/1.0\\r\\nConnection: close\\r\\n\\r\\n\")\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 480, in post_coroutine\n    return self.io_loop.run_sync(\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/ioloop.py\", line 407, in run_sync\n    raise TimeoutError('Operation timed out after %s seconds' % timeout)\ntornado.ioloop.TimeoutError: Operation timed out after 5 seconds\n__________ TestIOStreamWebHTTPS.test_future_read_until_close __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 595, in run\n    self._callTearDown()\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 553, in _callTearDown\n    self.tearDown()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 394, in tearDown\n    super(AsyncHTTPTestCase, self).tearDown()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 223, in tearDown\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/tcpserver.py\", line 214, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 405, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 386, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ TestIOStreamWebHTTPS.test_read_until_close __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 46, in test_read_until_close\n    self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/tcpserver.py\", line 214, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 405, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 386, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ TestIOStreamWebHTTPS.test_read_zero_bytes __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 58, in test_read_zero_bytes\n    self.wait()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/tcpserver.py\", line 214, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 405, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 386, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n__________ TestIOStreamWebHTTPS.test_write_while_connecting __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 112, in __call__\n    result = self.orig_method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/r2e_tests/test_1.py\", line 100, in test_write_while_connecting\n    self.wait(lambda: connected[0] and written[0])\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 305, in wait\n    self.__rethrow()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/testing.py\", line 241, in __rethrow\n    raise_exc_info(failure)\n  File \"<string>\", line 3, in raise_exc_info\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/stack_context.py\", line 314, in wrapped\n    ret = fn(*args, **kwargs)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 176, in accept_handler\n    callback(connection, address)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/tcpserver.py\", line 214, in _handle_connection\n    connection = ssl_wrap_socket(connection,\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 405, in ssl_wrap_socket\n    context = ssl_options_to_context(ssl_options)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/tornado_e22cd67dc86ab0f3bce9af401c94dca63dcac9af/tornado/netutil.py\", line 386, in ssl_options_to_context\n    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))\nssl.SSLError: [SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:4062)\n\n==================== short test summary info ====================\nPASSED r2e_tests.test_1::TestIOStream::test_async_read_error_logging\nPASSED r2e_tests.test_1::TestIOStream::test_close_buffered_data\nPASSED r2e_tests.test_1::TestIOStream::test_close_callback_with_pending_read\nPASSED r2e_tests.test_1::TestIOStream::test_connection_refused\nPASSED r2e_tests.test_1::TestIOStream::test_delayed_close_callback\nFAILED r2e_tests.test_1::TestIOStream::test_future_close_callback\nPASSED r2e_tests.test_1::TestIOStream::test_future_delayed_close_callback\nPASSED r2e_tests.test_1::TestIOStream::test_gaierror\nPASSED r2e_tests.test_1::TestIOStream::test_inline_read_error\nPASSED r2e_tests.test_1::TestIOStream::test_large_read_until\nPASSED r2e_tests.test_1::TestIOStream::test_read_callback_error\nPASSED r2e_tests.test_1::TestIOStream::test_read_until_close_after_close\nPASSED r2e_tests.test_1::TestIOStream::test_streaming_callback\nPASSED r2e_tests.test_1::TestIOStream::test_streaming_callback_with_data_in_buffer\nPASSED r2e_tests.test_1::TestIOStream::test_streaming_read_until_close_after_close\nPASSED r2e_tests.test_1::TestIOStream::test_streaming_until_close\nPASSED r2e_tests.test_1::TestIOStream::test_write_zero_bytes\nERROR r2e_tests.test_1::TestIOStreamSSL::test_async_read_error_logging\nERROR r2e_tests.test_1::TestIOStreamSSL::test_close_buffered_data\nERROR r2e_tests.test_1::TestIOStreamSSL::test_close_callback_with_pending_read\nPASSED r2e_tests.test_1::TestIOStreamSSL::test_connection_refused\nERROR r2e_tests.test_1::TestIOStreamSSL::test_delayed_close_callback\nERROR r2e_tests.test_1::TestIOStreamSSL::test_future_close_callback\nERROR r2e_tests.test_1::TestIOStreamSSL::test_future_delayed_close_callback\nPASSED r2e_tests.test_1::TestIOStreamSSL::test_gaierror\nERROR r2e_tests.test_1::TestIOStreamSSL::test_inline_read_error\nERROR r2e_tests.test_1::TestIOStreamSSL::test_large_read_until\nERROR r2e_tests.test_1::TestIOStreamSSL::test_read_callback_error\nERROR r2e_tests.test_1::TestIOStreamSSL::test_read_until_close_after_close\nERROR r2e_tests.test_1::TestIOStreamSSL::test_streaming_callback\nERROR r2e_tests.test_1::TestIOStreamSSL::test_streaming_callback_with_data_in_buffer\nERROR r2e_tests.test_1::TestIOStreamSSL::test_streaming_read_until_close_after_close\nERROR r2e_tests.test_1::TestIOStreamSSL::test_streaming_until_close\nERROR r2e_tests.test_1::TestIOStreamSSL::test_write_zero_bytes\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_async_read_error_logging\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_close_buffered_data\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_close_callback_with_pending_read\nPASSED r2e_tests.test_1::TestIOStreamSSLContext::test_connection_refused\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_delayed_close_callback\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_future_close_callback\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_future_delayed_close_callback\nPASSED r2e_tests.test_1::TestIOStreamSSLContext::test_gaierror\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_inline_read_error\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_large_read_until\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_read_callback_error\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_read_until_close_after_close\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_streaming_callback\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_streaming_callback_with_data_in_buffer\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_streaming_read_until_close_after_close\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_streaming_until_close\nERROR r2e_tests.test_1::TestIOStreamSSLContext::test_write_zero_bytes\nPASSED r2e_tests.test_1::TestIOStreamWebHTTP::test_connection_closed\nPASSED r2e_tests.test_1::TestIOStreamWebHTTP::test_future_close_while_reading\nPASSED r2e_tests.test_1::TestIOStreamWebHTTP::test_future_interface\nPASSED r2e_tests.test_1::TestIOStreamWebHTTP::test_future_read_until_close\nPASSED r2e_tests.test_1::TestIOStreamWebHTTP::test_read_until_close\nPASSED r2e_tests.test_1::TestIOStreamWebHTTP::test_read_zero_bytes\nPASSED r2e_tests.test_1::TestIOStreamWebHTTP::test_write_while_connecting\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_connection_closed\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_future_close_while_reading\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_future_close_while_reading\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_future_interface\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_future_interface\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_future_read_until_close\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_future_read_until_close\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_read_until_close\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_read_zero_bytes\nERROR r2e_tests.test_1::TestIOStreamWebHTTPS::test_write_while_connecting\nPASSED r2e_tests.test_1::TestPipeIOStream::test_pipe_iostream\nPASSED r2e_tests.test_1::TestPipeIOStream::test_pipe_iostream_big_write\n=================== 1 failed, 40 errors, 29 passed in 20.13s ===================\n",
    "old_commit_res_stderr": ""
}
tornado/iostream.py tornado/test/iostream_test.py
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]

**Close callback not invoked when using Future read interface**

**Description**
When using the Future-based read interface in `IOStream`, the `close_callback` is not triggered upon closing the client. This results in operations hanging or timing out because the callback never executes as expected.

**Example Code**
```python
server, client = self.make_iostream_pair()
closed = [False]

def close_callback():
    closed[0] = True
    self.stop()

server.set_close_callback(close_callback)

client.write(b'a')
future = server.read_bytes(1)
self.io_loop.add_future(future, self.stop)
result = self.wait().result()
print(result)  # Expected: b'a'
print(closed[0])  # Expected: False

client.close()
self.wait()
print(closed[0])  # Expected: True
```

**Expected Behavior**
After closing the client, the `close_callback` should be invoked, setting `closed[0]` to `True`. This ensures that any cleanup or follow-up actions tied to the callback are executed properly.

**Actual Behavior**
The `close_callback` is not called, leaving `closed[0]` as `False`. This causes the operation to hang and eventually timeout, as the expected callback execution does not occur.

[/ISSUE]
--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.

--- BEGIN FILE ---
```
### tornado/iostream.py
#!/usr/bin/env python
#
# Copyright 2009 Facebook
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

"""Utility classes to write to and read from non-blocking files and sockets.

Contents:

* `BaseIOStream`: Generic interface for reading and writing.
* `IOStream`: Implementation of BaseIOStream using non-blocking sockets.
* `SSLIOStream`: SSL-aware version of IOStream.
* `PipeIOStream`: Pipe-based IOStream implementation.
"""

from __future__ import absolute_import, division, print_function, with_statement

import collections
import errno
import numbers
import os
import socket
import ssl
import sys
import re

from tornado.concurrent import TracebackFuture
from tornado import ioloop
from tornado.log import gen_log, app_log
from tornado.netutil import ssl_wrap_socket, ssl_match_hostname, SSLCertificateError
from tornado import stack_context
from tornado.util import bytes_type

try:
    from tornado.platform.posix import _set_nonblocking
except ImportError:
    _set_nonblocking = None

# These errnos indicate that a non-blocking operation must be retried
# at a later time.  On most platforms they're the same value, but on
# some they differ.
_ERRNO_WOULDBLOCK = (errno.EWOULDBLOCK, errno.EAGAIN)

# These errnos indicate that a connection has been abruptly terminated.
# They should be caught and handled less noisily than other errors.
_ERRNO_CONNRESET = (errno.ECONNRESET, errno.ECONNABORTED, errno.EPIPE)


class StreamClosedError(IOError):
    """Exception raised by `IOStream` methods when the stream is closed.

    Note that the close callback is scheduled to run *after* other
    callbacks on the stream (to allow for buffered data to be processed),
    so you may see this error before you see the close callback.
    """
    pass


class BaseIOStream(object):
    """A utility class to write to and read from a non-blocking file or socket.

    We support a non-blocking ``write()`` and a family of ``read_*()`` methods.
    All of the methods take callbacks (since writing and reading are
    non-blocking and asynchronous).

    When a stream is closed due to an error, the IOStream's ``error``
    attribute contains the exception object.

    Subclasses must implement `fileno`, `close_fd`, `write_to_fd`,
    `read_from_fd`, and optionally `get_fd_error`.
    """
    def __init__(self, io_loop=None, max_buffer_size=None,
                 read_chunk_size=4096):
        self.io_loop = io_loop or ioloop.IOLoop.current()
        self.max_buffer_size = max_buffer_size or 104857600
        self.read_chunk_size = read_chunk_size
        self.error = None
        self._read_buffer = collections.deque()
        self._write_buffer = collections.deque()
        self._read_buffer_size = 0
        self._write_buffer_frozen = False
        self._read_delimiter = None
        self._read_regex = None
        self._read_bytes = None
        self._read_until_close = False
        self._read_callback = None
        self._read_future = None
        self._streaming_callback = None
        self._write_callback = None
        self._write_future = None
        self._close_callback = None
        self._connect_callback = None
        self._connect_future = None
        self._connecting = False
        self._state = None
        self._pending_callbacks = 0
        self._closed = False

    def fileno(self):
        """Returns the file descriptor for this stream."""
        raise NotImplementedError()

    def close_fd(self):
        """Closes the file underlying this stream.

        ``close_fd`` is called by `BaseIOStream` and should not be called
        elsewhere; other users should call `close` instead.
        """
        raise NotImplementedError()

    def write_to_fd(self, data):
        """Attempts to write ``data`` to the underlying file.

        Returns the number of bytes written.
        """
        raise NotImplementedError()

    def read_from_fd(self):
        """Attempts to read from the underlying file.

        Returns ``None`` if there was nothing to read (the socket
        returned `~errno.EWOULDBLOCK` or equivalent), otherwise
        returns the data.  When possible, should return no more than
        ``self.read_chunk_size`` bytes at a time.
        """
        raise NotImplementedError()

    def get_fd_error(self):
        """Returns information about any error on the underlying file.

        This method is called after the `.IOLoop` has signaled an error on the
        file descriptor, and should return an Exception (such as `socket.error`
        with additional information, or None if no such information is
        available.
        """
        return None

    def read_until_regex(self, regex, callback=None):
        """Run ``callback`` when we read the given regex pattern.

        The callback will get the data read (including the data that
        matched the regex and anything that came before it) as an argument.
        """
        future = self._set_read_callback(callback)
        self._read_regex = re.compile(regex)
        self._try_inline_read()
        return future

    def read_until(self, delimiter, callback=None):
        """Run ``callback`` when we read the given delimiter.

        The callback will get the data read (including the delimiter)
        as an argument.
        """
        future = self._set_read_callback(callback)
        self._read_delimiter = delimiter
        self._try_inline_read()
        return future

    def read_bytes(self, num_bytes, callback=None, streaming_callback=None):
        """Run callback when we read the given number of bytes.

        If a ``streaming_callback`` is given, it will be called with chunks
        of data as they become available, and the argument to the final
        ``callback`` will be empty.  Otherwise, the ``callback`` gets
        the data as an argument.
        """
        future = self._set_read_callback(callback)
        assert isinstance(num_bytes, numbers.Integral)
        self._read_bytes = num_bytes
        self._streaming_callback = stack_context.wrap(streaming_callback)
        self._try_inline_read()
        return future

    def read_until_close(self, callback=None, streaming_callback=None):
        """Reads all data from the socket until it is closed.

        If a ``streaming_callback`` is given, it will be called with chunks
        of data as they become available, and the argument to the final
        ``callback`` will be empty.  Otherwise, the ``callback`` gets the
        data as an argument.

        Subject to ``max_buffer_size`` limit from `IOStream` constructor if
        a ``streaming_callback`` is not used.
        """
        future = self._set_read_callback(callback)
        self._streaming_callback = stack_context.wrap(streaming_callback)
        if self.closed():
            if self._streaming_callback is not None:
                self._run_callback(self._streaming_callback,
                                   self._consume(self._read_buffer_size))
            self._run_read_callback(self._consume(self._read_buffer_size))
            return future
        self._read_until_close = True
        self._streaming_callback = stack_context.wrap(streaming_callback)
        self._try_inline_read()
        return future

    def write(self, data, callback=None):
        """Write the given data to this stream.

        If ``callback`` is given, we call it when all of the buffered write
        data has been successfully written to the stream. If there was
        previously buffered write data and an old write callback, that
        callback is simply overwritten with this new callback.
        """
        assert isinstance(data, bytes_type)
        self._check_closed()
        # We use bool(_write_buffer) as a proxy for write_buffer_size>0,
        # so never put empty strings in the buffer.
        if data:
            # Break up large contiguous strings before inserting them in the
            # write buffer, so we don't have to recopy the entire thing
            # as we slice off pieces to send to the socket.
            WRITE_BUFFER_CHUNK_SIZE = 128 * 1024
            for i in range(0, len(data), WRITE_BUFFER_CHUNK_SIZE):
                self._write_buffer.append(data[i:i + WRITE_BUFFER_CHUNK_SIZE])
        if callback is not None:
            self._write_callback = stack_context.wrap(callback)
            future = None
        else:
            future = self._write_future = TracebackFuture()
        if not self._connecting:
            self._handle_write()
            if self._write_buffer:
                self._add_io_state(self.io_loop.WRITE)
            self._maybe_add_error_listener()
        return future

    def set_close_callback(self, callback):
        """Call the given callback when the stream is closed."""
        self._close_callback = stack_context.wrap(callback)

    def close(self, exc_info=False):
        """Close this stream.

        If ``exc_info`` is true, set the ``error`` attribute to the current
        exception from `sys.exc_info` (or if ``exc_info`` is a tuple,
        use that instead of `sys.exc_info`).
        """
        if not self.closed():
            if exc_info:
                if not isinstance(exc_info, tuple):
                    exc_info = sys.exc_info()
                if any(exc_info):
                    self.error = exc_info[1]
            if self._read_until_close:
                if (self._streaming_callback is not None and
                        self._read_buffer_size):
                    self._run_callback(self._streaming_callback,
                                       self._consume(self._read_buffer_size))
                self._read_until_close = False
                self._run_read_callback(self._consume(self._read_buffer_size))
            if self._state is not None:
                self.io_loop.remove_handler(self.fileno())
                self._state = None
            self.close_fd()
            self._closed = True
        self._maybe_run_close_callback()

    def _maybe_run_close_callback(self):
        # If there are pending callbacks, don't run the close callback
        # until they're done (see _maybe_add_error_handler)
        if self.closed() and self._pending_callbacks == 0:
            futures = []
            if self._read_future is not None:
                futures.append(self._read_future)
                self._read_future = None
            if self._write_future is not None:
                futures.append(self._write_future)
                self._write_future = None
            if self._connect_future is not None:
                futures.append(self._connect_future)
                self._connect_future = None
            for future in futures:
                future.set_exception(StreamClosedError())
            if self._close_callback is not None:
                cb = self._close_callback
                self._close_callback = None
                self._run_callback(cb)
            # Delete any unfinished callbacks to break up reference cycles.
            self._read_callback = self._write_callback = None
            # Clear the buffers so they can be cleared immediately even
            # if the IOStream object is kept alive by a reference cycle.
            # TODO: Clear the read buffer too; it currently breaks some tests.
            self._write_buffer = None

    def reading(self):
        """Returns true if we are currently reading from the stream."""
        return self._read_callback is not None

    def writing(self):
        """Returns true if we are currently writing to the stream."""
        return bool(self._write_buffer)

    def closed(self):
        """Returns true if the stream has been closed."""
        return self._closed

    def set_nodelay(self, value):
        """Sets the no-delay flag for this stream.

        By default, data written to TCP streams may be held for a time
        to make the most efficient use of bandwidth (according to
        Nagle's algorithm).  The no-delay flag requests that data be
        written as soon as possible, even if doing so would consume
        additional bandwidth.

        This flag is currently defined only for TCP-based ``IOStreams``.

        .. versionadded:: 3.1
        """
        pass

    def _handle_events(self, fd, events):
        if self.closed():
            gen_log.warning("Got events for closed stream %s", fd)
            return
        try:
            if events & self.io_loop.READ:
                self._handle_read()
            if self.closed():
                return
            if events & self.io_loop.WRITE:
                if self._connecting:
                    self._handle_connect()
                self._handle_write()
            if self.closed():
                return
            if events & self.io_loop.ERROR:
                self.error = self.get_fd_error()
                # We may have queued up a user callback in _handle_read or
                # _handle_write, so don't close the IOStream until those
                # callbacks have had a chance to run.
                self.io_loop.add_callback(self.close)
                return
            state = self.io_loop.ERROR
            if self.reading():
                state |= self.io_loop.READ
            if self.writing():
                state |= self.io_loop.WRITE
            if state == self.io_loop.ERROR:
                state |= self.io_loop.READ
            if state != self._state:
                assert self._state is not None, \
                    "shouldn't happen: _handle_events without self._state"
                self._state = state
                self.io_loop.update_handler(self.fileno(), self._state)
        except Exception:
            gen_log.error("Uncaught exception, closing connection.",
                          exc_info=True)
            self.close(exc_info=True)
            raise

    def _run_callback(self, callback, *args):
        def wrapper():
            self._pending_callbacks -= 1
            try:
                callback(*args)
            except Exception:
                app_log.error("Uncaught exception, closing connection.",
                              exc_info=True)
                # Close the socket on an uncaught exception from a user callback
                # (It would eventually get closed when the socket object is
                # gc'd, but we don't want to rely on gc happening before we
                # run out of file descriptors)
                self.close(exc_info=True)
                # Re-raise the exception so that IOLoop.handle_callback_exception
                # can see it and log the error
                raise
            self._maybe_add_error_listener()
        # We schedule callbacks to be run on the next IOLoop iteration
        # rather than running them directly for several reasons:
        # * Prevents unbounded stack growth when a callback calls an
        #   IOLoop operation that immediately runs another callback
        # * Provides a predictable execution context for e.g.
        #   non-reentrant mutexes
        # * Ensures that the try/except in wrapper() is run outside
        #   of the application's StackContexts
        with stack_context.NullContext():
            # stack_context was already captured in callback, we don't need to
            # capture it again for IOStream's wrapper.  This is especially
            # important if the callback was pre-wrapped before entry to
            # IOStream (as in HTTPConnection._header_callback), as we could
            # capture and leak the wrong context here.
            self._pending_callbacks += 1
            self.io_loop.add_callback(wrapper)

    def _handle_read(self):
        try:
            try:
                # Pretend to have a pending callback so that an EOF in
                # _read_to_buffer doesn't trigger an immediate close
                # callback.  At the end of this method we'll either
                # estabilsh a real pending callback via
                # _read_from_buffer or run the close callback.
                #
                # We need two try statements here so that
                # pending_callbacks is decremented before the `except`
                # clause below (which calls `close` and does need to
                # trigger the callback)
                self._pending_callbacks += 1
                while not self.closed():
                    # Read from the socket until we get EWOULDBLOCK or equivalent.
                    # SSL sockets do some internal buffering, and if the data is
                    # sitting in the SSL object's buffer select() and friends
                    # can't see it; the only way to find out if it's there is to
                    # try to read it.
                    if self._read_to_buffer() == 0:
                        break
            finally:
                self._pending_callbacks -= 1
        except Exception:
            gen_log.warning("error on read", exc_info=True)
            self.close(exc_info=True)
            return
        if self._read_from_buffer():
            return
        else:
            self._maybe_run_close_callback()

    def _set_read_callback(self, callback):
        assert self._read_callback is None, "Already reading"
        assert self._read_future is None, "Already reading"
        if callback is not None:
            self._read_callback = stack_context.wrap(callback)
        else:
            self._read_future = TracebackFuture()
        return self._read_future

    def _run_read_callback(self, data):
        self._streaming_callback = None
        if self._read_future is not None:
            future = self._read_future
            self._read_future = None
            future.set_result(data)
        if self._read_callback is not None:
            callback = self._read_callback
            self._read_callback = None
            self._run_callback(callback, data)

    def _try_inline_read(self):
        """Attempt to complete the current read operation from buffered data.

        If the read can be completed without blocking, schedules the
        read callback on the next IOLoop iteration; otherwise starts
        listening for reads on the socket.
        """
        # See if we've already got the data from a previous read
        if self._read_from_buffer():
            return
        self._check_closed()
        try:
            try:
                # See comments in _handle_read about incrementing _pending_callbacks
                self._pending_callbacks += 1
                while not self.closed():
                    if self._read_to_buffer() == 0:
                        break
            finally:
                self._pending_callbacks -= 1
        except Exception:
            # If there was an in _read_to_buffer, we called close() already,
            # but couldn't run the close callback because of _pending_callbacks.
            # Before we escape from this function, run the close callback if
            # applicable.
            self._maybe_run_close_callback()
            raise
        if self._read_from_buffer():
            return
        self._maybe_add_error_listener()

    def _read_to_buffer(self):
        """Reads from the socket and appends the result to the read buffer.

        Returns the number of bytes read.  Returns 0 if there is nothing
        to read (i.e. the read returns EWOULDBLOCK or equivalent).  On
        error closes the socket and raises an exception.
        """
        try:
            chunk = self.read_from_fd()
        except (socket.error, IOError, OSError) as e:
            # ssl.SSLError is a subclass of socket.error
            if e.args[0] in _ERRNO_CONNRESET:
                # Treat ECONNRESET as a connection close rather than
                # an error to minimize log spam  (the exception will
                # be available on self.error for apps that care).
                self.close(exc_info=True)
                return
            self.close(exc_info=True)
            raise
        if chunk is None:
            return 0
        self._read_buffer.append(chunk)
        self._read_buffer_size += len(chunk)
        if self._read_buffer_size >= self.max_buffer_size:
            gen_log.error("Reached maximum read buffer size")
            self.close()
            raise IOError("Reached maximum read buffer size")
        return len(chunk)

    def _read_from_buffer(self):
        """Attempts to complete the currently-pending read from the buffer.

        Returns True if the read was completed.
        """
        if self._streaming_callback is not None and self._read_buffer_size:
            bytes_to_consume = self._read_buffer_size
            if self._read_bytes is not None:
                bytes_to_consume = min(self._read_bytes, bytes_to_consume)
                self._read_bytes -= bytes_to_consume
            self._run_callback(self._streaming_callback,
                               self._consume(bytes_to_consume))
        if self._read_bytes is not None and self._read_buffer_size >= self._read_bytes:
            num_bytes = self._read_bytes
            self._read_bytes = None
            self._run_read_callback(self._consume(num_bytes))
            return True
        elif self._read_delimiter is not None:
            # Multi-byte delimiters (e.g. '\r\n') may straddle two
            # chunks in the read buffer, so we can't easily find them
            # without collapsing the buffer.  However, since protocols
            # using delimited reads (as opposed to reads of a known
            # length) tend to be "line" oriented, the delimiter is likely
            # to be in the first few chunks.  Merge the buffer gradually
            # since large merges are relatively expensive and get undone in
            # consume().
            if self._read_buffer:
                while True:
                    loc = self._read_buffer[0].find(self._read_delimiter)
                    if loc != -1:
                        delimiter_len = len(self._read_delimiter)
                        self._read_delimiter = None
                        self._run_read_callback(
                            self._consume(loc + delimiter_len))
                        return True
                    if len(self._read_buffer) == 1:
                        break
                    _double_prefix(self._read_buffer)
        elif self._read_regex is not None:
            if self._read_buffer:
                while True:
                    m = self._read_regex.search(self._read_buffer[0])
                    if m is not None:
                        self._read_regex = None
                        self._run_read_callback(self._consume(m.end()))
                        return True
                    if len(self._read_buffer) == 1:
                        break
                    _double_prefix(self._read_buffer)
        return False

    def _handle_write(self):
        while self._write_buffer:
            try:
                if not self._write_buffer_frozen:
                    # On windows, socket.send blows up if given a
                    # write buffer that's too large, instead of just
                    # returning the number of bytes it was able to
                    # process.  Therefore we must not call socket.send
                    # with more than 128KB at a time.
                    _merge_prefix(self._write_buffer, 128 * 1024)
                num_bytes = self.write_to_fd(self._write_buffer[0])
                if num_bytes == 0:
                    # With OpenSSL, if we couldn't write the entire buffer,
                    # the very same string object must be used on the
                    # next call to send.  Therefore we suppress
                    # merging the write buffer after an incomplete send.
                    # A cleaner solution would be to set
                    # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, but this is
                    # not yet accessible from python
                    # (http://bugs.python.org/issue8240)
                    self._write_buffer_frozen = True
                    break
                self._write_buffer_frozen = False
                _merge_prefix(self._write_buffer, num_bytes)
                self._write_buffer.popleft()
            except (socket.error, IOError, OSError) as e:
                if e.args[0] in _ERRNO_WOULDBLOCK:
                    self._write_buffer_frozen = True
                    break
                else:
                    if e.args[0] not in _ERRNO_CONNRESET:
                        # Broken pipe errors are usually caused by connection
                        # reset, and its better to not log EPIPE errors to
                        # minimize log spam
                        gen_log.warning("Write error on %s: %s",
                                        self.fileno(), e)
                    self.close(exc_info=True)
                    return
        if not self._write_buffer:
            if self._write_callback:
                callback = self._write_callback
                self._write_callback = None
                self._run_callback(callback)
            if self._write_future:
                future = self._write_future
                self._write_future = None
                future.set_result(None)

    def _consume(self, loc):
        if loc == 0:
            return b""
        _merge_prefix(self._read_buffer, loc)
        self._read_buffer_size -= loc
        return self._read_buffer.popleft()

    def _check_closed(self):
        if self.closed():
            raise StreamClosedError("Stream is closed")

    def _maybe_add_error_listener(self):
        if self._state is None and self._pending_callbacks == 0:
            if self.closed():
                self._maybe_run_close_callback()
            else:
                self._add_io_state(ioloop.IOLoop.READ)

    def _add_io_state(self, state):
        """Adds `state` (IOLoop.{READ,WRITE} flags) to our event handler.

        Implementation notes: Reads and writes have a fast path and a
        slow path.  The fast path reads synchronously from socket
        buffers, while the slow path uses `_add_io_state` to schedule
        an IOLoop callback.  Note that in both cases, the callback is
        run asynchronously with `_run_callback`.

        To detect closed connections, we must have called
        `_add_io_state` at some point, but we want to delay this as
        much as possible so we don't have to set an `IOLoop.ERROR`
        listener that will be overwritten by the next slow-path
        operation.  As long as there are callbacks scheduled for
        fast-path ops, those callbacks may do more reads.
        If a sequence of fast-path ops do not end in a slow-path op,
        (e.g. for an @asynchronous long-poll request), we must add
        the error handler.  This is done in `_run_callback` and `write`
        (since the write callback is optional so we can have a
        fast-path write with no `_run_callback`)
        """
        if self.closed():
            # connection has been closed, so there can be no future events
            return
        if self._state is None:
            self._state = ioloop.IOLoop.ERROR | state
            with stack_context.NullContext():
                self.io_loop.add_handler(
                    self.fileno(), self._handle_events, self._state)
        elif not self._state & state:
            self._state = self._state | state
            self.io_loop.update_handler(self.fileno(), self._state)


class IOStream(BaseIOStream):
    r"""Socket-based `IOStream` implementation.

    This class supports the read and write methods from `BaseIOStream`
    plus a `connect` method.

    The ``socket`` parameter may either be connected or unconnected.
    For server operations the socket is the result of calling
    `socket.accept <socket.socket.accept>`.  For client operations the
    socket is created with `socket.socket`, and may either be
    connected before passing it to the `IOStream` or connected with
    `IOStream.connect`.

    A very simple (and broken) HTTP client using this class::

        import tornado.ioloop
        import tornado.iostream
        import socket

        def send_request():
            stream.write(b"GET / HTTP/1.0\r\nHost: friendfeed.com\r\n\r\n")
            stream.read_until(b"\r\n\r\n", on_headers)

        def on_headers(data):
            headers = {}
            for line in data.split(b"\r\n"):
               parts = line.split(b":")
               if len(parts) == 2:
                   headers[parts[0].strip()] = parts[1].strip()
            stream.read_bytes(int(headers[b"Content-Length"]), on_body)

        def on_body(data):
            print data
            stream.close()
            tornado.ioloop.IOLoop.instance().stop()

        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
        stream = tornado.iostream.IOStream(s)
        stream.connect(("friendfeed.com", 80), send_request)
        tornado.ioloop.IOLoop.instance().start()
    """
    def __init__(self, socket, *args, **kwargs):
        self.socket = socket
        self.socket.setblocking(False)
        super(IOStream, self).__init__(*args, **kwargs)

    def fileno(self):
        return self.socket

    def close_fd(self):
        self.socket.close()
        self.socket = None

    def get_fd_error(self):
        errno = self.socket.getsockopt(socket.SOL_SOCKET,
                                       socket.SO_ERROR)
        return socket.error(errno, os.strerror(errno))

    def read_from_fd(self):
        try:
            chunk = self.socket.recv(self.read_chunk_size)
        except socket.error as e:
            if e.args[0] in _ERRNO_WOULDBLOCK:
                return None
            else:
                raise
        if not chunk:
            self.close()
            return None
        return chunk

    def write_to_fd(self, data):
        return self.socket.send(data)

    def connect(self, address, callback=None, server_hostname=None):
        """Connects the socket to a remote address without blocking.

        May only be called if the socket passed to the constructor was
        not previously connected.  The address parameter is in the
        same format as for `socket.connect <socket.socket.connect>`,
        i.e. a ``(host, port)`` tuple.  If ``callback`` is specified,
        it will be called when the connection is completed.

        If specified, the ``server_hostname`` parameter will be used
        in SSL connections for certificate validation (if requested in
        the ``ssl_options``) and SNI (if supported; requires
        Python 3.2+).

        Note that it is safe to call `IOStream.write
        <BaseIOStream.write>` while the connection is pending, in
        which case the data will be written as soon as the connection
        is ready.  Calling `IOStream` read methods before the socket is
        connected works on some platforms but is non-portable.
        """
        self._connecting = True
        try:
            self.socket.connect(address)
        except socket.error as e:
            # In non-blocking mode we expect connect() to raise an
            # exception with EINPROGRESS or EWOULDBLOCK.
            #
            # On freebsd, other errors such as ECONNREFUSED may be
            # returned immediately when attempting to connect to
            # localhost, so handle them the same way as an error
            # reported later in _handle_connect.
            if (e.args[0] != errno.EINPROGRESS and
                    e.args[0] not in _ERRNO_WOULDBLOCK):
                gen_log.warning("Connect error on fd %s: %s",
                                self.socket.fileno(), e)
                self.close(exc_info=True)
                return
        if callback is not None:
            self._connect_callback = stack_context.wrap(callback)
            future = None
        else:
            future = self._connect_future = TracebackFuture()
        self._add_io_state(self.io_loop.WRITE)
        return future

    def _handle_connect(self):
        err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
        if err != 0:
            self.error = socket.error(err, os.strerror(err))
            # IOLoop implementations may vary: some of them return
            # an error state before the socket becomes writable, so
            # in that case a connection failure would be handled by the
            # error path in _handle_events instead of here.
            gen_log.warning("Connect error on fd %s: %s",
                            self.socket.fileno(), errno.errorcode[err])
            self.close()
            return
        if self._connect_callback is not None:
            callback = self._connect_callback
            self._connect_callback = None
            self._run_callback(callback)
        if self._connect_future is not None:
            future = self._connect_future
            self._connect_future = None
            future.set_result(None)
        self._connecting = False

    def set_nodelay(self, value):
        if (self.socket is not None and
                self.socket.family in (socket.AF_INET, socket.AF_INET6)):
            try:
                self.socket.setsockopt(socket.IPPROTO_TCP,
                                       socket.TCP_NODELAY, 1 if value else 0)
            except socket.error as e:
                # Sometimes setsockopt will fail if the socket is closed
                # at the wrong time.  This can happen with HTTPServer
                # resetting the value to false between requests.
                if e.errno not in (errno.EINVAL, errno.ECONNRESET):
                    raise


class SSLIOStream(IOStream):
    """A utility class to write to and read from a non-blocking SSL socket.

    If the socket passed to the constructor is already connected,
    it should be wrapped with::

        ssl.wrap_socket(sock, do_handshake_on_connect=False, **kwargs)

    before constructing the `SSLIOStream`.  Unconnected sockets will be
    wrapped when `IOStream.connect` is finished.
    """
    def __init__(self, *args, **kwargs):
        """The ``ssl_options`` keyword argument may either be a dictionary
        of keywords arguments for `ssl.wrap_socket`, or an `ssl.SSLContext`
        object.
        """
        self._ssl_options = kwargs.pop('ssl_options', {})
        super(SSLIOStream, self).__init__(*args, **kwargs)
        self._ssl_accepting = True
        self._handshake_reading = False
        self._handshake_writing = False
        self._ssl_connect_callback = None
        self._server_hostname = None

        # If the socket is already connected, attempt to start the handshake.
        try:
            self.socket.getpeername()
        except socket.error:
            pass
        else:
            # Indirectly start the handshake, which will run on the next
            # IOLoop iteration and then the real IO state will be set in
            # _handle_events.
            self._add_io_state(self.io_loop.WRITE)

    def reading(self):
        return self._handshake_reading or super(SSLIOStream, self).reading()

    def writing(self):
        return self._handshake_writing or super(SSLIOStream, self).writing()

    def _do_ssl_handshake(self):
        # Based on code from test_ssl.py in the python stdlib
        try:
            self._handshake_reading = False
            self._handshake_writing = False
            self.socket.do_handshake()
        except ssl.SSLError as err:
            if err.args[0] == ssl.SSL_ERROR_WANT_READ:
                self._handshake_reading = True
                return
            elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
                self._handshake_writing = True
                return
            elif err.args[0] in (ssl.SSL_ERROR_EOF,
                                 ssl.SSL_ERROR_ZERO_RETURN):
                return self.close(exc_info=True)
            elif err.args[0] == ssl.SSL_ERROR_SSL:
                try:
                    peer = self.socket.getpeername()
                except Exception:
                    peer = '(not connected)'
                gen_log.warning("SSL Error on %s %s: %s",
                                self.socket.fileno(), peer, err)
                return self.close(exc_info=True)
            raise
        except socket.error as err:
            if err.args[0] in _ERRNO_CONNRESET:
                return self.close(exc_info=True)
        except AttributeError:
            # On Linux, if the connection was reset before the call to
            # wrap_socket, do_handshake will fail with an
            # AttributeError.
            return self.close(exc_info=True)
        else:
            self._ssl_accepting = False
            if not self._verify_cert(self.socket.getpeercert()):
                self.close()
                return
            if self._ssl_connect_callback is not None:
                callback = self._ssl_connect_callback
                self._ssl_connect_callback = None
                self._run_callback(callback)

    def _verify_cert(self, peercert):
        """Returns True if peercert is valid according to the configured
        validation mode and hostname.

        The ssl handshake already tested the certificate for a valid
        CA signature; the only thing that remains is to check
        the hostname.
        """
        if isinstance(self._ssl_options, dict):
            verify_mode = self._ssl_options.get('cert_reqs', ssl.CERT_NONE)
        elif isinstance(self._ssl_options, ssl.SSLContext):
            verify_mode = self._ssl_options.verify_mode
        assert verify_mode in (ssl.CERT_NONE, ssl.CERT_REQUIRED, ssl.CERT_OPTIONAL)
        if verify_mode == ssl.CERT_NONE or self._server_hostname is None:
            return True
        cert = self.socket.getpeercert()
        if cert is None and verify_mode == ssl.CERT_REQUIRED:
            gen_log.warning("No SSL certificate given")
            return False
        try:
            ssl_match_hostname(peercert, self._server_hostname)
        except SSLCertificateError:
            gen_log.warning("Invalid SSL certificate", exc_info=True)
            return False
        else:
            return True

    def _handle_read(self):
        if self._ssl_accepting:
            self._do_ssl_handshake()
            return
        super(SSLIOStream, self)._handle_read()

    def _handle_write(self):
        if self._ssl_accepting:
            self._do_ssl_handshake()
            return
        super(SSLIOStream, self)._handle_write()

    def connect(self, address, callback=None, server_hostname=None):
        # Save the user's callback and run it after the ssl handshake
        # has completed.
        self._ssl_connect_callback = stack_context.wrap(callback)
        self._server_hostname = server_hostname
        # Note: Since we don't pass our callback argument along to
        # super.connect(), this will always return a Future.
        # This is harmless, but a bit less efficient than it could be.
        return super(SSLIOStream, self).connect(address, callback=None)

    def _handle_connect(self):
        # When the connection is complete, wrap the socket for SSL
        # traffic.  Note that we do this by overriding _handle_connect
        # instead of by passing a callback to super().connect because
        # user callbacks are enqueued asynchronously on the IOLoop,
        # but since _handle_events calls _handle_connect immediately
        # followed by _handle_write we need this to be synchronous.
        #
        # The IOLoop will get confused if we swap out self.socket while the
        # fd is registered, so remove it now and re-register after
        # wrap_socket().
        self.io_loop.remove_handler(self.socket)
        old_state = self._state
        self._state = None
        self.socket = ssl_wrap_socket(self.socket, self._ssl_options,
                                      server_hostname=self._server_hostname,
                                      do_handshake_on_connect=False)
        self._add_io_state(old_state)
        super(SSLIOStream, self)._handle_connect()

    def read_from_fd(self):
        if self._ssl_accepting:
            # If the handshake hasn't finished yet, there can't be anything
            # to read (attempting to read may or may not raise an exception
            # depending on the SSL version)
            return None
        try:
            # SSLSocket objects have both a read() and recv() method,
            # while regular sockets only have recv().
            # The recv() method blocks (at least in python 2.6) if it is
            # called when there is nothing to read, so we have to use
            # read() instead.
            chunk = self.socket.read(self.read_chunk_size)
        except ssl.SSLError as e:
            # SSLError is a subclass of socket.error, so this except
            # block must come first.
            if e.args[0] == ssl.SSL_ERROR_WANT_READ:
                return None
            else:
                raise
        except socket.error as e:
            if e.args[0] in _ERRNO_WOULDBLOCK:
                return None
            else:
                raise
        if not chunk:
            self.close()
            return None
        return chunk


class PipeIOStream(BaseIOStream):
    """Pipe-based `IOStream` implementation.

    The constructor takes an integer file descriptor (such as one returned
    by `os.pipe`) rather than an open file object.  Pipes are generally
    one-way, so a `PipeIOStream` can be used for reading or writing but not
    both.
    """
    def __init__(self, fd, *args, **kwargs):
        self.fd = fd
        _set_nonblocking(fd)
        super(PipeIOStream, self).__init__(*args, **kwargs)

    def fileno(self):
        return self.fd

    def close_fd(self):
        os.close(self.fd)

    def write_to_fd(self, data):
        return os.write(self.fd, data)

    def read_from_fd(self):
        try:
            chunk = os.read(self.fd, self.read_chunk_size)
        except (IOError, OSError) as e:
            if e.args[0] in _ERRNO_WOULDBLOCK:
                return None
            elif e.args[0] == errno.EBADF:
                # If the writing half of a pipe is closed, select will
                # report it as readable but reads will fail with EBADF.
                self.close(exc_info=True)
                return None
            else:
                raise
        if not chunk:
            self.close()
            return None
        return chunk


def _double_prefix(deque):
    """Grow by doubling, but don't split the second chunk just because the
    first one is small.
    """
    new_len = max(len(deque[0]) * 2,
                  (len(deque[0]) + len(deque[1])))
    _merge_prefix(deque, new_len)


def _merge_prefix(deque, size):
    """Replace the first entries in a deque of strings with a single
    string of up to size bytes.

    >>> d = collections.deque(['abc', 'de', 'fghi', 'j'])
    >>> _merge_prefix(d, 5); print(d)
    deque(['abcde', 'fghi', 'j'])

    Strings will be split as necessary to reach the desired size.
    >>> _merge_prefix(d, 7); print(d)
    deque(['abcdefg', 'hi', 'j'])

    >>> _merge_prefix(d, 3); print(d)
    deque(['abc', 'defg', 'hi', 'j'])

    >>> _merge_prefix(d, 100); print(d)
    deque(['abcdefghij'])
    """
    if len(deque) == 1 and len(deque[0]) <= size:
        return
    prefix = []
    remaining = size
    while deque and remaining > 0:
        chunk = deque.popleft()
        if len(chunk) > remaining:
            deque.appendleft(chunk[remaining:])
            chunk = chunk[:remaining]
        prefix.append(chunk)
        remaining -= len(chunk)
    # This data structure normally just contains byte strings, but
    # the unittest gets messy if it doesn't use the default str() type,
    # so do the merge based on the type of data that's actually present.
    if prefix:
        deque.appendleft(type(prefix[0])().join(prefix))
    if not deque:
        deque.appendleft(b"")


def doctests():
    import doctest
    return doctest.DocTestSuite()

```
--- END FILE ---

Please first localize the bug based on the issue statement, and then generate *SEARCH/REPLACE* edits to fix the issue.

Every *SEARCH/REPLACE* edit must use this format:
1. The file path
2. The start of search block: <<<<<<< SEARCH
3. A contiguous chunk of lines to search for in the existing source code
4. The dividing line: =======
5. The lines to replace into the source code
6. The end of the replace block: >>>>>>> REPLACE

Here is an example:

```python
### mathweb/flask/app.py
<<<<<<< SEARCH
from flask import Flask
=======
import math
from flask import Flask
>>>>>>> REPLACE
```
</solution>

Please note that the *SEARCH/REPLACE* edit REQUIRES PROPER INDENTATION. If you would like to add the line '        print(x)', you must fully write that out, with all those spaces before the code!
Wrap each *SEARCH/REPLACE* edit in a code block as shown in the example above. If you have multiple *SEARCH/REPLACE* edits, use a separate code block for each one.
[ISSUE]

**Close callback not invoked when using Future read interface**

**Description**
When using the Future-based read interface in `IOStream`, the `close_callback` is not triggered upon closing the client. This results in operations hanging or timing out because the callback never executes as expected.

**Example Code**
```python
server, client = self.make_iostream_pair()
closed = [False]

def close_callback():
    closed[0] = True
    self.stop()

server.set_close_callback(close_callback)

client.write(b'a')
future = server.read_bytes(1)
self.io_loop.add_future(future, self.stop)
result = self.wait().result()
print(result)  # Expected: b'a'
print(closed[0])  # Expected: False

client.close()
self.wait()
print(closed[0])  # Expected: True
```

**Expected Behavior**
After closing the client, the `close_callback` should be invoked, setting `closed[0]` to `True`. This ensures that any cleanup or follow-up actions tied to the callback are executed properly.

**Actual Behavior**
The `close_callback` is not called, leaving `closed[0]` as `False`. This causes the operation to hang and eventually timeout, as the expected callback execution does not occur.

[/ISSUE]
{
    "TestIOStream.test_async_read_error_logging": "PASSED",
    "TestIOStream.test_close_buffered_data": "PASSED",
    "TestIOStream.test_close_callback_with_pending_read": "PASSED",
    "TestIOStream.test_connection_refused": "PASSED",
    "TestIOStream.test_delayed_close_callback": "PASSED",
    "TestIOStream.test_future_close_callback": "PASSED",
    "TestIOStream.test_future_delayed_close_callback": "PASSED",
    "TestIOStream.test_gaierror": "PASSED",
    "TestIOStream.test_inline_read_error": "PASSED",
    "TestIOStream.test_large_read_until": "PASSED",
    "TestIOStream.test_read_callback_error": "PASSED",
    "TestIOStream.test_read_until_close_after_close": "PASSED",
    "TestIOStream.test_streaming_callback": "PASSED",
    "TestIOStream.test_streaming_callback_with_data_in_buffer": "PASSED",
    "TestIOStream.test_streaming_read_until_close_after_close": "PASSED",
    "TestIOStream.test_streaming_until_close": "PASSED",
    "TestIOStream.test_write_zero_bytes": "PASSED",
    "TestIOStreamSSL.test_async_read_error_logging": "ERROR",
    "TestIOStreamSSL.test_close_buffered_data": "ERROR",
    "TestIOStreamSSL.test_close_callback_with_pending_read": "ERROR",
    "TestIOStreamSSL.test_connection_refused": "PASSED",
    "TestIOStreamSSL.test_delayed_close_callback": "ERROR",
    "TestIOStreamSSL.test_future_close_callback": "ERROR",
    "TestIOStreamSSL.test_future_delayed_close_callback": "ERROR",
    "TestIOStreamSSL.test_gaierror": "PASSED",
    "TestIOStreamSSL.test_inline_read_error": "ERROR",
    "TestIOStreamSSL.test_large_read_until": "ERROR",
    "TestIOStreamSSL.test_read_callback_error": "ERROR",
    "TestIOStreamSSL.test_read_until_close_after_close": "ERROR",
    "TestIOStreamSSL.test_streaming_callback": "ERROR",
    "TestIOStreamSSL.test_streaming_callback_with_data_in_buffer": "ERROR",
    "TestIOStreamSSL.test_streaming_read_until_close_after_close": "ERROR",
    "TestIOStreamSSL.test_streaming_until_close": "ERROR",
    "TestIOStreamSSL.test_write_zero_bytes": "ERROR",
    "TestIOStreamSSLContext.test_async_read_error_logging": "ERROR",
    "TestIOStreamSSLContext.test_close_buffered_data": "ERROR",
    "TestIOStreamSSLContext.test_close_callback_with_pending_read": "ERROR",
    "TestIOStreamSSLContext.test_connection_refused": "PASSED",
    "TestIOStreamSSLContext.test_delayed_close_callback": "ERROR",
    "TestIOStreamSSLContext.test_future_close_callback": "ERROR",
    "TestIOStreamSSLContext.test_future_delayed_close_callback": "ERROR",
    "TestIOStreamSSLContext.test_gaierror": "PASSED",
    "TestIOStreamSSLContext.test_inline_read_error": "ERROR",
    "TestIOStreamSSLContext.test_large_read_until": "ERROR",
    "TestIOStreamSSLContext.test_read_callback_error": "ERROR",
    "TestIOStreamSSLContext.test_read_until_close_after_close": "ERROR",
    "TestIOStreamSSLContext.test_streaming_callback": "ERROR",
    "TestIOStreamSSLContext.test_streaming_callback_with_data_in_buffer": "ERROR",
    "TestIOStreamSSLContext.test_streaming_read_until_close_after_close": "ERROR",
    "TestIOStreamSSLContext.test_streaming_until_close": "ERROR",
    "TestIOStreamSSLContext.test_write_zero_bytes": "ERROR",
    "TestIOStreamWebHTTP.test_connection_closed": "PASSED",
    "TestIOStreamWebHTTP.test_future_close_while_reading": "PASSED",
    "TestIOStreamWebHTTP.test_future_interface": "PASSED",
    "TestIOStreamWebHTTP.test_future_read_until_close": "PASSED",
    "TestIOStreamWebHTTP.test_read_until_close": "PASSED",
    "TestIOStreamWebHTTP.test_read_zero_bytes": "PASSED",
    "TestIOStreamWebHTTP.test_write_while_connecting": "PASSED",
    "TestIOStreamWebHTTPS.test_connection_closed": "ERROR",
    "TestIOStreamWebHTTPS.test_future_close_while_reading": "ERROR",
    "TestIOStreamWebHTTPS.test_future_interface": "ERROR",
    "TestIOStreamWebHTTPS.test_future_read_until_close": "ERROR",
    "TestIOStreamWebHTTPS.test_read_until_close": "ERROR",
    "TestIOStreamWebHTTPS.test_read_zero_bytes": "ERROR",
    "TestIOStreamWebHTTPS.test_write_while_connecting": "ERROR",
    "TestPipeIOStream.test_pipe_iostream": "PASSED",
    "TestPipeIOStream.test_pipe_iostream_big_write": "PASSED"
}
diff --git a/tornado/iostream.py b/tornado/iostream.py
index faf657a4..113ee094 100644
--- a/tornado/iostream.py
+++ b/tornado/iostream.py
@@ -449,6 +449,10 @@ class BaseIOStream(object):
             callback = self._read_callback
             self._read_callback = None
             self._run_callback(callback, data)
+        else:
+            # If we scheduled a callback, we will add the error listener
+            # afterwards.  If we didn't, we have to do it now.
+            self._maybe_add_error_listener()
 
     def _try_inline_read(self):
         """Attempt to complete the current read operation from buffered data.

{"tornado/iostream.py": "#!/usr/bin/env python\n#\n# Copyright 2009 Facebook\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n# not use this file except in compliance with the License. You may obtain\n# a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n# License for the specific language governing permissions and limitations\n# under the License.\n\n\"\"\"Utility classes to write to and read from non-blocking files and sockets.\n\nContents:\n\n* `BaseIOStream`: Generic interface for reading and writing.\n* `IOStream`: Implementation of BaseIOStream using non-blocking sockets.\n* `SSLIOStream`: SSL-aware version of IOStream.\n* `PipeIOStream`: Pipe-based IOStream implementation.\n\"\"\"\n\nfrom __future__ import absolute_import, division, print_function, with_statement\n\nimport collections\nimport errno\nimport numbers\nimport os\nimport socket\nimport ssl\nimport sys\nimport re\n\nfrom tornado.concurrent import TracebackFuture\nfrom tornado import ioloop\nfrom tornado.log import gen_log, app_log\nfrom tornado.netutil import ssl_wrap_socket, ssl_match_hostname, SSLCertificateError\nfrom tornado import stack_context\nfrom tornado.util import bytes_type\n\ntry:\n    from tornado.platform.posix import _set_nonblocking\nexcept ImportError:\n    _set_nonblocking = None\n\n# These errnos indicate that a non-blocking operation must be retried\n# at a later time.  On most platforms they're the same value, but on\n# some they differ.\n_ERRNO_WOULDBLOCK = (errno.EWOULDBLOCK, errno.EAGAIN)\n\n# These errnos indicate that a connection has been abruptly terminated.\n# They should be caught and handled less noisily than other errors.\n_ERRNO_CONNRESET = (errno.ECONNRESET, errno.ECONNABORTED, errno.EPIPE)\n\n\nclass StreamClosedError(IOError):\n    \"\"\"Exception raised by `IOStream` methods when the stream is closed.\n\n    Note that the close callback is scheduled to run *after* other\n    callbacks on the stream (to allow for buffered data to be processed),\n    so you may see this error before you see the close callback.\n    \"\"\"\n    pass\n\n\nclass BaseIOStream(object):\n    \"\"\"A utility class to write to and read from a non-blocking file or socket.\n\n    We support a non-blocking ``write()`` and a family of ``read_*()`` methods.\n    All of the methods take callbacks (since writing and reading are\n    non-blocking and asynchronous).\n\n    When a stream is closed due to an error, the IOStream's ``error``\n    attribute contains the exception object.\n\n    Subclasses must implement `fileno`, `close_fd`, `write_to_fd`,\n    `read_from_fd`, and optionally `get_fd_error`.\n    \"\"\"\n    def __init__(self, io_loop=None, max_buffer_size=None,\n                 read_chunk_size=4096):\n        self.io_loop = io_loop or ioloop.IOLoop.current()\n        self.max_buffer_size = max_buffer_size or 104857600\n        self.read_chunk_size = read_chunk_size\n        self.error = None\n        self._read_buffer = collections.deque()\n        self._write_buffer = collections.deque()\n        self._read_buffer_size = 0\n        self._write_buffer_frozen = False\n        self._read_delimiter = None\n        self._read_regex = None\n        self._read_bytes = None\n        self._read_until_close = False\n        self._read_callback = None\n        self._read_future = None\n        self._streaming_callback = None\n        self._write_callback = None\n        self._write_future = None\n        self._close_callback = None\n        self._connect_callback = None\n        self._connect_future = None\n        self._connecting = False\n        self._state = None\n        self._pending_callbacks = 0\n        self._closed = False\n\n    def fileno(self):\n        \"\"\"Returns the file descriptor for this stream.\"\"\"\n        raise NotImplementedError()\n\n    def close_fd(self):\n        \"\"\"Closes the file underlying this stream.\n\n        ``close_fd`` is called by `BaseIOStream` and should not be called\n        elsewhere; other users should call `close` instead.\n        \"\"\"\n        raise NotImplementedError()\n\n    def write_to_fd(self, data):\n        \"\"\"Attempts to write ``data`` to the underlying file.\n\n        Returns the number of bytes written.\n        \"\"\"\n        raise NotImplementedError()\n\n    def read_from_fd(self):\n        \"\"\"Attempts to read from the underlying file.\n\n        Returns ``None`` if there was nothing to read (the socket\n        returned `~errno.EWOULDBLOCK` or equivalent), otherwise\n        returns the data.  When possible, should return no more than\n        ``self.read_chunk_size`` bytes at a time.\n        \"\"\"\n        raise NotImplementedError()\n\n    def get_fd_error(self):\n        \"\"\"Returns information about any error on the underlying file.\n\n        This method is called after the `.IOLoop` has signaled an error on the\n        file descriptor, and should return an Exception (such as `socket.error`\n        with additional information, or None if no such information is\n        available.\n        \"\"\"\n        return None\n\n    def read_until_regex(self, regex, callback=None):\n        \"\"\"Run ``callback`` when we read the given regex pattern.\n\n        The callback will get the data read (including the data that\n        matched the regex and anything that came before it) as an argument.\n        \"\"\"\n        future = self._set_read_callback(callback)\n        self._read_regex = re.compile(regex)\n        self._try_inline_read()\n        return future\n\n    def read_until(self, delimiter, callback=None):\n        \"\"\"Run ``callback`` when we read the given delimiter.\n\n        The callback will get the data read (including the delimiter)\n        as an argument.\n        \"\"\"\n        future = self._set_read_callback(callback)\n        self._read_delimiter = delimiter\n        self._try_inline_read()\n        return future\n\n    def read_bytes(self, num_bytes, callback=None, streaming_callback=None):\n        \"\"\"Run callback when we read the given number of bytes.\n\n        If a ``streaming_callback`` is given, it will be called with chunks\n        of data as they become available, and the argument to the final\n        ``callback`` will be empty.  Otherwise, the ``callback`` gets\n        the data as an argument.\n        \"\"\"\n        future = self._set_read_callback(callback)\n        assert isinstance(num_bytes, numbers.Integral)\n        self._read_bytes = num_bytes\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        self._try_inline_read()\n        return future\n\n    def read_until_close(self, callback=None, streaming_callback=None):\n        \"\"\"Reads all data from the socket until it is closed.\n\n        If a ``streaming_callback`` is given, it will be called with chunks\n        of data as they become available, and the argument to the final\n        ``callback`` will be empty.  Otherwise, the ``callback`` gets the\n        data as an argument.\n\n        Subject to ``max_buffer_size`` limit from `IOStream` constructor if\n        a ``streaming_callback`` is not used.\n        \"\"\"\n        future = self._set_read_callback(callback)\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        if self.closed():\n            if self._streaming_callback is not None:\n                self._run_callback(self._streaming_callback,\n                                   self._consume(self._read_buffer_size))\n            self._run_read_callback(self._consume(self._read_buffer_size))\n            return future\n        self._read_until_close = True\n        self._streaming_callback = stack_context.wrap(streaming_callback)\n        self._try_inline_read()\n        return future\n\n    def write(self, data, callback=None):\n        \"\"\"Write the given data to this stream.\n\n        If ``callback`` is given, we call it when all of the buffered write\n        data has been successfully written to the stream. If there was\n        previously buffered write data and an old write callback, that\n        callback is simply overwritten with this new callback.\n        \"\"\"\n        assert isinstance(data, bytes_type)\n        self._check_closed()\n        # We use bool(_write_buffer) as a proxy for write_buffer_size>0,\n        # so never put empty strings in the buffer.\n        if data:\n            # Break up large contiguous strings before inserting them in the\n            # write buffer, so we don't have to recopy the entire thing\n            # as we slice off pieces to send to the socket.\n            WRITE_BUFFER_CHUNK_SIZE = 128 * 1024\n            for i in range(0, len(data), WRITE_BUFFER_CHUNK_SIZE):\n                self._write_buffer.append(data[i:i + WRITE_BUFFER_CHUNK_SIZE])\n        if callback is not None:\n            self._write_callback = stack_context.wrap(callback)\n            future = None\n        else:\n            future = self._write_future = TracebackFuture()\n        if not self._connecting:\n            self._handle_write()\n            if self._write_buffer:\n                self._add_io_state(self.io_loop.WRITE)\n            self._maybe_add_error_listener()\n        return future\n\n    def set_close_callback(self, callback):\n        \"\"\"Call the given callback when the stream is closed.\"\"\"\n        self._close_callback = stack_context.wrap(callback)\n\n    def close(self, exc_info=False):\n        \"\"\"Close this stream.\n\n        If ``exc_info`` is true, set the ``error`` attribute to the current\n        exception from `sys.exc_info` (or if ``exc_info`` is a tuple,\n        use that instead of `sys.exc_info`).\n        \"\"\"\n        if not self.closed():\n            if exc_info:\n                if not isinstance(exc_info, tuple):\n                    exc_info = sys.exc_info()\n                if any(exc_info):\n                    self.error = exc_info[1]\n            if self._read_until_close:\n                if (self._streaming_callback is not None and\n                        self._read_buffer_size):\n                    self._run_callback(self._streaming_callback,\n                                       self._consume(self._read_buffer_size))\n                self._read_until_close = False\n                self._run_read_callback(self._consume(self._read_buffer_size))\n            if self._state is not None:\n                self.io_loop.remove_handler(self.fileno())\n                self._state = None\n            self.close_fd()\n            self._closed = True\n        self._maybe_run_close_callback()\n\n    def _maybe_run_close_callback(self):\n        # If there are pending callbacks, don't run the close callback\n        # until they're done (see _maybe_add_error_handler)\n        if self.closed() and self._pending_callbacks == 0:\n            futures = []\n            if self._read_future is not None:\n                futures.append(self._read_future)\n                self._read_future = None\n            if self._write_future is not None:\n                futures.append(self._write_future)\n                self._write_future = None\n            if self._connect_future is not None:\n                futures.append(self._connect_future)\n                self._connect_future = None\n            for future in futures:\n                future.set_exception(StreamClosedError())\n            if self._close_callback is not None:\n                cb = self._close_callback\n                self._close_callback = None\n                self._run_callback(cb)\n            # Delete any unfinished callbacks to break up reference cycles.\n            self._read_callback = self._write_callback = None\n            # Clear the buffers so they can be cleared immediately even\n            # if the IOStream object is kept alive by a reference cycle.\n            # TODO: Clear the read buffer too; it currently breaks some tests.\n            self._write_buffer = None\n\n    def reading(self):\n        \"\"\"Returns true if we are currently reading from the stream.\"\"\"\n        return self._read_callback is not None\n\n    def writing(self):\n        \"\"\"Returns true if we are currently writing to the stream.\"\"\"\n        return bool(self._write_buffer)\n\n    def closed(self):\n        \"\"\"Returns true if the stream has been closed.\"\"\"\n        return self._closed\n\n    def set_nodelay(self, value):\n        \"\"\"Sets the no-delay flag for this stream.\n\n        By default, data written to TCP streams may be held for a time\n        to make the most efficient use of bandwidth (according to\n        Nagle's algorithm).  The no-delay flag requests that data be\n        written as soon as possible, even if doing so would consume\n        additional bandwidth.\n\n        This flag is currently defined only for TCP-based ``IOStreams``.\n\n        .. versionadded:: 3.1\n        \"\"\"\n        pass\n\n    def _handle_events(self, fd, events):\n        if self.closed():\n            gen_log.warning(\"Got events for closed stream %s\", fd)\n            return\n        try:\n            if events & self.io_loop.READ:\n                self._handle_read()\n            if self.closed():\n                return\n            if events & self.io_loop.WRITE:\n                if self._connecting:\n                    self._handle_connect()\n                self._handle_write()\n            if self.closed():\n                return\n            if events & self.io_loop.ERROR:\n                self.error = self.get_fd_error()\n                # We may have queued up a user callback in _handle_read or\n                # _handle_write, so don't close the IOStream until those\n                # callbacks have had a chance to run.\n                self.io_loop.add_callback(self.close)\n                return\n            state = self.io_loop.ERROR\n            if self.reading():\n                state |= self.io_loop.READ\n            if self.writing():\n                state |= self.io_loop.WRITE\n            if state == self.io_loop.ERROR:\n                state |= self.io_loop.READ\n            if state != self._state:\n                assert self._state is not None, \\\n                    \"shouldn't happen: _handle_events without self._state\"\n                self._state = state\n                self.io_loop.update_handler(self.fileno(), self._state)\n        except Exception:\n            gen_log.error(\"Uncaught exception, closing connection.\",\n                          exc_info=True)\n            self.close(exc_info=True)\n            raise\n\n    def _run_callback(self, callback, *args):\n        def wrapper():\n            self._pending_callbacks -= 1\n            try:\n                callback(*args)\n            except Exception:\n                app_log.error(\"Uncaught exception, closing connection.\",\n                              exc_info=True)\n                # Close the socket on an uncaught exception from a user callback\n                # (It would eventually get closed when the socket object is\n                # gc'd, but we don't want to rely on gc happening before we\n                # run out of file descriptors)\n                self.close(exc_info=True)\n                # Re-raise the exception so that IOLoop.handle_callback_exception\n                # can see it and log the error\n                raise\n            self._maybe_add_error_listener()\n        # We schedule callbacks to be run on the next IOLoop iteration\n        # rather than running them directly for several reasons:\n        # * Prevents unbounded stack growth when a callback calls an\n        #   IOLoop operation that immediately runs another callback\n        # * Provides a predictable execution context for e.g.\n        #   non-reentrant mutexes\n        # * Ensures that the try/except in wrapper() is run outside\n        #   of the application's StackContexts\n        with stack_context.NullContext():\n            # stack_context was already captured in callback, we don't need to\n            # capture it again for IOStream's wrapper.  This is especially\n            # important if the callback was pre-wrapped before entry to\n            # IOStream (as in HTTPConnection._header_callback), as we could\n            # capture and leak the wrong context here.\n            self._pending_callbacks += 1\n            self.io_loop.add_callback(wrapper)\n\n    def _handle_read(self):\n        try:\n            try:\n                # Pretend to have a pending callback so that an EOF in\n                # _read_to_buffer doesn't trigger an immediate close\n                # callback.  At the end of this method we'll either\n                # estabilsh a real pending callback via\n                # _read_from_buffer or run the close callback.\n                #\n                # We need two try statements here so that\n                # pending_callbacks is decremented before the `except`\n                # clause below (which calls `close` and does need to\n                # trigger the callback)\n                self._pending_callbacks += 1\n                while not self.closed():\n                    # Read from the socket until we get EWOULDBLOCK or equivalent.\n                    # SSL sockets do some internal buffering, and if the data is\n                    # sitting in the SSL object's buffer select() and friends\n                    # can't see it; the only way to find out if it's there is to\n                    # try to read it.\n                    if self._read_to_buffer() == 0:\n                        break\n            finally:\n                self._pending_callbacks -= 1\n        except Exception:\n            gen_log.warning(\"error on read\", exc_info=True)\n            self.close(exc_info=True)\n            return\n        if self._read_from_buffer():\n            return\n        else:\n            self._maybe_run_close_callback()\n\n    def _set_read_callback(self, callback):\n        assert self._read_callback is None, \"Already reading\"\n        assert self._read_future is None, \"Already reading\"\n        if callback is not None:\n            self._read_callback = stack_context.wrap(callback)\n        else:\n            self._read_future = TracebackFuture()\n        return self._read_future\n\n    def _run_read_callback(self, data):\n        self._streaming_callback = None\n        if self._read_future is not None:\n            future = self._read_future\n            self._read_future = None\n            future.set_result(data)\n        if self._read_callback is not None:\n            callback = self._read_callback\n            self._read_callback = None\n            self._run_callback(callback, data)\n\n    def _try_inline_read(self):\n        \"\"\"Attempt to complete the current read operation from buffered data.\n\n        If the read can be completed without blocking, schedules the\n        read callback on the next IOLoop iteration; otherwise starts\n        listening for reads on the socket.\n        \"\"\"\n        # See if we've already got the data from a previous read\n        if self._read_from_buffer():\n            return\n        self._check_closed()\n        try:\n            try:\n                # See comments in _handle_read about incrementing _pending_callbacks\n                self._pending_callbacks += 1\n                while not self.closed():\n                    if self._read_to_buffer() == 0:\n                        break\n            finally:\n                self._pending_callbacks -= 1\n        except Exception:\n            # If there was an in _read_to_buffer, we called close() already,\n            # but couldn't run the close callback because of _pending_callbacks.\n            # Before we escape from this function, run the close callback if\n            # applicable.\n            self._maybe_run_close_callback()\n            raise\n        if self._read_from_buffer():\n            return\n        self._maybe_add_error_listener()\n\n    def _read_to_buffer(self):\n        \"\"\"Reads from the socket and appends the result to the read buffer.\n\n        Returns the number of bytes read.  Returns 0 if there is nothing\n        to read (i.e. the read returns EWOULDBLOCK or equivalent).  On\n        error closes the socket and raises an exception.\n        \"\"\"\n        try:\n            chunk = self.read_from_fd()\n        except (socket.error, IOError, OSError) as e:\n            # ssl.SSLError is a subclass of socket.error\n            if e.args[0] in _ERRNO_CONNRESET:\n                # Treat ECONNRESET as a connection close rather than\n                # an error to minimize log spam  (the exception will\n                # be available on self.error for apps that care).\n                self.close(exc_info=True)\n                return\n            self.close(exc_info=True)\n            raise\n        if chunk is None:\n            return 0\n        self._read_buffer.append(chunk)\n        self._read_buffer_size += len(chunk)\n        if self._read_buffer_size >= self.max_buffer_size:\n            gen_log.error(\"Reached maximum read buffer size\")\n            self.close()\n            raise IOError(\"Reached maximum read buffer size\")\n        return len(chunk)\n\n    def _read_from_buffer(self):\n        \"\"\"Attempts to complete the currently-pending read from the buffer.\n\n        Returns True if the read was completed.\n        \"\"\"\n        if self._streaming_callback is not None and self._read_buffer_size:\n            bytes_to_consume = self._read_buffer_size\n            if self._read_bytes is not None:\n                bytes_to_consume = min(self._read_bytes, bytes_to_consume)\n                self._read_bytes -= bytes_to_consume\n            self._run_callback(self._streaming_callback,\n                               self._consume(bytes_to_consume))\n        if self._read_bytes is not None and self._read_buffer_size >= self._read_bytes:\n            num_bytes = self._read_bytes\n            self._read_bytes = None\n            self._run_read_callback(self._consume(num_bytes))\n            return True\n        elif self._read_delimiter is not None:\n            # Multi-byte delimiters (e.g. '\\r\\n') may straddle two\n            # chunks in the read buffer, so we can't easily find them\n            # without collapsing the buffer.  However, since protocols\n            # using delimited reads (as opposed to reads of a known\n            # length) tend to be \"line\" oriented, the delimiter is likely\n            # to be in the first few chunks.  Merge the buffer gradually\n            # since large merges are relatively expensive and get undone in\n            # consume().\n            if self._read_buffer:\n                while True:\n                    loc = self._read_buffer[0].find(self._read_delimiter)\n                    if loc != -1:\n                        delimiter_len = len(self._read_delimiter)\n                        self._read_delimiter = None\n                        self._run_read_callback(\n                            self._consume(loc + delimiter_len))\n                        return True\n                    if len(self._read_buffer) == 1:\n                        break\n                    _double_prefix(self._read_buffer)\n        elif self._read_regex is not None:\n            if self._read_buffer:\n                while True:\n                    m = self._read_regex.search(self._read_buffer[0])\n                    if m is not None:\n                        self._read_regex = None\n                        self._run_read_callback(self._consume(m.end()))\n                        return True\n                    if len(self._read_buffer) == 1:\n                        break\n                    _double_prefix(self._read_buffer)\n        return False\n\n    def _handle_write(self):\n        while self._write_buffer:\n            try:\n                if not self._write_buffer_frozen:\n                    # On windows, socket.send blows up if given a\n                    # write buffer that's too large, instead of just\n                    # returning the number of bytes it was able to\n                    # process.  Therefore we must not call socket.send\n                    # with more than 128KB at a time.\n                    _merge_prefix(self._write_buffer, 128 * 1024)\n                num_bytes = self.write_to_fd(self._write_buffer[0])\n                if num_bytes == 0:\n                    # With OpenSSL, if we couldn't write the entire buffer,\n                    # the very same string object must be used on the\n                    # next call to send.  Therefore we suppress\n                    # merging the write buffer after an incomplete send.\n                    # A cleaner solution would be to set\n                    # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, but this is\n                    # not yet accessible from python\n                    # (http://bugs.python.org/issue8240)\n                    self._write_buffer_frozen = True\n                    break\n                self._write_buffer_frozen = False\n                _merge_prefix(self._write_buffer, num_bytes)\n                self._write_buffer.popleft()\n            except (socket.error, IOError, OSError) as e:\n                if e.args[0] in _ERRNO_WOULDBLOCK:\n                    self._write_buffer_frozen = True\n                    break\n                else:\n                    if e.args[0] not in _ERRNO_CONNRESET:\n                        # Broken pipe errors are usually caused by connection\n                        # reset, and its better to not log EPIPE errors to\n                        # minimize log spam\n                        gen_log.warning(\"Write error on %s: %s\",\n                                        self.fileno(), e)\n                    self.close(exc_info=True)\n                    return\n        if not self._write_buffer:\n            if self._write_callback:\n                callback = self._write_callback\n                self._write_callback = None\n                self._run_callback(callback)\n            if self._write_future:\n                future = self._write_future\n                self._write_future = None\n                future.set_result(None)\n\n    def _consume(self, loc):\n        if loc == 0:\n            return b\"\"\n        _merge_prefix(self._read_buffer, loc)\n        self._read_buffer_size -= loc\n        return self._read_buffer.popleft()\n\n    def _check_closed(self):\n        if self.closed():\n            raise StreamClosedError(\"Stream is closed\")\n\n    def _maybe_add_error_listener(self):\n        if self._state is None and self._pending_callbacks == 0:\n            if self.closed():\n                self._maybe_run_close_callback()\n            else:\n                self._add_io_state(ioloop.IOLoop.READ)\n\n    def _add_io_state(self, state):\n        \"\"\"Adds `state` (IOLoop.{READ,WRITE} flags) to our event handler.\n\n        Implementation notes: Reads and writes have a fast path and a\n        slow path.  The fast path reads synchronously from socket\n        buffers, while the slow path uses `_add_io_state` to schedule\n        an IOLoop callback.  Note that in both cases, the callback is\n        run asynchronously with `_run_callback`.\n\n        To detect closed connections, we must have called\n        `_add_io_state` at some point, but we want to delay this as\n        much as possible so we don't have to set an `IOLoop.ERROR`\n        listener that will be overwritten by the next slow-path\n        operation.  As long as there are callbacks scheduled for\n        fast-path ops, those callbacks may do more reads.\n        If a sequence of fast-path ops do not end in a slow-path op,\n        (e.g. for an @asynchronous long-poll request), we must add\n        the error handler.  This is done in `_run_callback` and `write`\n        (since the write callback is optional so we can have a\n        fast-path write with no `_run_callback`)\n        \"\"\"\n        if self.closed():\n            # connection has been closed, so there can be no future events\n            return\n        if self._state is None:\n            self._state = ioloop.IOLoop.ERROR | state\n            with stack_context.NullContext():\n                self.io_loop.add_handler(\n                    self.fileno(), self._handle_events, self._state)\n        elif not self._state & state:\n            self._state = self._state | state\n            self.io_loop.update_handler(self.fileno(), self._state)\n\n\nclass IOStream(BaseIOStream):\n    r\"\"\"Socket-based `IOStream` implementation.\n\n    This class supports the read and write methods from `BaseIOStream`\n    plus a `connect` method.\n\n    The ``socket`` parameter may either be connected or unconnected.\n    For server operations the socket is the result of calling\n    `socket.accept <socket.socket.accept>`.  For client operations the\n    socket is created with `socket.socket`, and may either be\n    connected before passing it to the `IOStream` or connected with\n    `IOStream.connect`.\n\n    A very simple (and broken) HTTP client using this class::\n\n        import tornado.ioloop\n        import tornado.iostream\n        import socket\n\n        def send_request():\n            stream.write(b\"GET / HTTP/1.0\\r\\nHost: friendfeed.com\\r\\n\\r\\n\")\n            stream.read_until(b\"\\r\\n\\r\\n\", on_headers)\n\n        def on_headers(data):\n            headers = {}\n            for line in data.split(b\"\\r\\n\"):\n               parts = line.split(b\":\")\n               if len(parts) == 2:\n                   headers[parts[0].strip()] = parts[1].strip()\n            stream.read_bytes(int(headers[b\"Content-Length\"]), on_body)\n\n        def on_body(data):\n            print data\n            stream.close()\n            tornado.ioloop.IOLoop.instance().stop()\n\n        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)\n        stream = tornado.iostream.IOStream(s)\n        stream.connect((\"friendfeed.com\", 80), send_request)\n        tornado.ioloop.IOLoop.instance().start()\n    \"\"\"\n    def __init__(self, socket, *args, **kwargs):\n        self.socket = socket\n        self.socket.setblocking(False)\n        super(IOStream, self).__init__(*args, **kwargs)\n\n    def fileno(self):\n        return self.socket\n\n    def close_fd(self):\n        self.socket.close()\n        self.socket = None\n\n    def get_fd_error(self):\n        errno = self.socket.getsockopt(socket.SOL_SOCKET,\n                                       socket.SO_ERROR)\n        return socket.error(errno, os.strerror(errno))\n\n    def read_from_fd(self):\n        try:\n            chunk = self.socket.recv(self.read_chunk_size)\n        except socket.error as e:\n            if e.args[0] in _ERRNO_WOULDBLOCK:\n                return None\n            else:\n                raise\n        if not chunk:\n            self.close()\n            return None\n        return chunk\n\n    def write_to_fd(self, data):\n        return self.socket.send(data)\n\n    def connect(self, address, callback=None, server_hostname=None):\n        \"\"\"Connects the socket to a remote address without blocking.\n\n        May only be called if the socket passed to the constructor was\n        not previously connected.  The address parameter is in the\n        same format as for `socket.connect <socket.socket.connect>`,\n        i.e. a ``(host, port)`` tuple.  If ``callback`` is specified,\n        it will be called when the connection is completed.\n\n        If specified, the ``server_hostname`` parameter will be used\n        in SSL connections for certificate validation (if requested in\n        the ``ssl_options``) and SNI (if supported; requires\n        Python 3.2+).\n\n        Note that it is safe to call `IOStream.write\n        <BaseIOStream.write>` while the connection is pending, in\n        which case the data will be written as soon as the connection\n        is ready.  Calling `IOStream` read methods before the socket is\n        connected works on some platforms but is non-portable.\n        \"\"\"\n        self._connecting = True\n        try:\n            self.socket.connect(address)\n        except socket.error as e:\n            # In non-blocking mode we expect connect() to raise an\n            # exception with EINPROGRESS or EWOULDBLOCK.\n            #\n            # On freebsd, other errors such as ECONNREFUSED may be\n            # returned immediately when attempting to connect to\n            # localhost, so handle them the same way as an error\n            # reported later in _handle_connect.\n            if (e.args[0] != errno.EINPROGRESS and\n                    e.args[0] not in _ERRNO_WOULDBLOCK):\n                gen_log.warning(\"Connect error on fd %s: %s\",\n                                self.socket.fileno(), e)\n                self.close(exc_info=True)\n                return\n        if callback is not None:\n            self._connect_callback = stack_context.wrap(callback)\n            future = None\n        else:\n            future = self._connect_future = TracebackFuture()\n        self._add_io_state(self.io_loop.WRITE)\n        return future\n\n    def _handle_connect(self):\n        err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)\n        if err != 0:\n            self.error = socket.error(err, os.strerror(err))\n            # IOLoop implementations may vary: some of them return\n            # an error state before the socket becomes writable, so\n            # in that case a connection failure would be handled by the\n            # error path in _handle_events instead of here.\n            gen_log.warning(\"Connect error on fd %s: %s\",\n                            self.socket.fileno(), errno.errorcode[err])\n            self.close()\n            return\n        if self._connect_callback is not None:\n            callback = self._connect_callback\n            self._connect_callback = None\n            self._run_callback(callback)\n        if self._connect_future is not None:\n            future = self._connect_future\n            self._connect_future = None\n            future.set_result(None)\n        self._connecting = False\n\n    def set_nodelay(self, value):\n        if (self.socket is not None and\n                self.socket.family in (socket.AF_INET, socket.AF_INET6)):\n            try:\n                self.socket.setsockopt(socket.IPPROTO_TCP,\n                                       socket.TCP_NODELAY, 1 if value else 0)\n            except socket.error as e:\n                # Sometimes setsockopt will fail if the socket is closed\n                # at the wrong time.  This can happen with HTTPServer\n                # resetting the value to false between requests.\n                if e.errno not in (errno.EINVAL, errno.ECONNRESET):\n                    raise\n\n\nclass SSLIOStream(IOStream):\n    \"\"\"A utility class to write to and read from a non-blocking SSL socket.\n\n    If the socket passed to the constructor is already connected,\n    it should be wrapped with::\n\n        ssl.wrap_socket(sock, do_handshake_on_connect=False, **kwargs)\n\n    before constructing the `SSLIOStream`.  Unconnected sockets will be\n    wrapped when `IOStream.connect` is finished.\n    \"\"\"\n    def __init__(self, *args, **kwargs):\n        \"\"\"The ``ssl_options`` keyword argument may either be a dictionary\n        of keywords arguments for `ssl.wrap_socket`, or an `ssl.SSLContext`\n        object.\n        \"\"\"\n        self._ssl_options = kwargs.pop('ssl_options', {})\n        super(SSLIOStream, self).__init__(*args, **kwargs)\n        self._ssl_accepting = True\n        self._handshake_reading = False\n        self._handshake_writing = False\n        self._ssl_connect_callback = None\n        self._server_hostname = None\n\n        # If the socket is already connected, attempt to start the handshake.\n        try:\n            self.socket.getpeername()\n        except socket.error:\n            pass\n        else:\n            # Indirectly start the handshake, which will run on the next\n            # IOLoop iteration and then the real IO state will be set in\n            # _handle_events.\n            self._add_io_state(self.io_loop.WRITE)\n\n    def reading(self):\n        return self._handshake_reading or super(SSLIOStream, self).reading()\n\n    def writing(self):\n        return self._handshake_writing or super(SSLIOStream, self).writing()\n\n    def _do_ssl_handshake(self):\n        # Based on code from test_ssl.py in the python stdlib\n        try:\n            self._handshake_reading = False\n            self._handshake_writing = False\n            self.socket.do_handshake()\n        except ssl.SSLError as err:\n            if err.args[0] == ssl.SSL_ERROR_WANT_READ:\n                self._handshake_reading = True\n                return\n            elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:\n                self._handshake_writing = True\n                return\n            elif err.args[0] in (ssl.SSL_ERROR_EOF,\n                                 ssl.SSL_ERROR_ZERO_RETURN):\n                return self.close(exc_info=True)\n            elif err.args[0] == ssl.SSL_ERROR_SSL:\n                try:\n                    peer = self.socket.getpeername()\n                except Exception:\n                    peer = '(not connected)'\n                gen_log.warning(\"SSL Error on %s %s: %s\",\n                                self.socket.fileno(), peer, err)\n                return self.close(exc_info=True)\n            raise\n        except socket.error as err:\n            if err.args[0] in _ERRNO_CONNRESET:\n                return self.close(exc_info=True)\n        except AttributeError:\n            # On Linux, if the connection was reset before the call to\n            # wrap_socket, do_handshake will fail with an\n            # AttributeError.\n            return self.close(exc_info=True)\n        else:\n            self._ssl_accepting = False\n            if not self._verify_cert(self.socket.getpeercert()):\n                self.close()\n                return\n            if self._ssl_connect_callback is not None:\n                callback = self._ssl_connect_callback\n                self._ssl_connect_callback = None\n                self._run_callback(callback)\n\n    def _verify_cert(self, peercert):\n        \"\"\"Returns True if peercert is valid according to the configured\n        validation mode and hostname.\n\n        The ssl handshake already tested the certificate for a valid\n        CA signature; the only thing that remains is to check\n        the hostname.\n        \"\"\"\n        if isinstance(self._ssl_options, dict):\n            verify_mode = self._ssl_options.get('cert_reqs', ssl.CERT_NONE)\n        elif isinstance(self._ssl_options, ssl.SSLContext):\n            verify_mode = self._ssl_options.verify_mode\n        assert verify_mode in (ssl.CERT_NONE, ssl.CERT_REQUIRED, ssl.CERT_OPTIONAL)\n        if verify_mode == ssl.CERT_NONE or self._server_hostname is None:\n            return True\n        cert = self.socket.getpeercert()\n        if cert is None and verify_mode == ssl.CERT_REQUIRED:\n            gen_log.warning(\"No SSL certificate given\")\n            return False\n        try:\n            ssl_match_hostname(peercert, self._server_hostname)\n        except SSLCertificateError:\n            gen_log.warning(\"Invalid SSL certificate\", exc_info=True)\n            return False\n        else:\n            return True\n\n    def _handle_read(self):\n        if self._ssl_accepting:\n            self._do_ssl_handshake()\n            return\n        super(SSLIOStream, self)._handle_read()\n\n    def _handle_write(self):\n        if self._ssl_accepting:\n            self._do_ssl_handshake()\n            return\n        super(SSLIOStream, self)._handle_write()\n\n    def connect(self, address, callback=None, server_hostname=None):\n        # Save the user's callback and run it after the ssl handshake\n        # has completed.\n        self._ssl_connect_callback = stack_context.wrap(callback)\n        self._server_hostname = server_hostname\n        # Note: Since we don't pass our callback argument along to\n        # super.connect(), this will always return a Future.\n        # This is harmless, but a bit less efficient than it could be.\n        return super(SSLIOStream, self).connect(address, callback=None)\n\n    def _handle_connect(self):\n        # When the connection is complete, wrap the socket for SSL\n        # traffic.  Note that we do this by overriding _handle_connect\n        # instead of by passing a callback to super().connect because\n        # user callbacks are enqueued asynchronously on the IOLoop,\n        # but since _handle_events calls _handle_connect immediately\n        # followed by _handle_write we need this to be synchronous.\n        #\n        # The IOLoop will get confused if we swap out self.socket while the\n        # fd is registered, so remove it now and re-register after\n        # wrap_socket().\n        self.io_loop.remove_handler(self.socket)\n        old_state = self._state\n        self._state = None\n        self.socket = ssl_wrap_socket(self.socket, self._ssl_options,\n                                      server_hostname=self._server_hostname,\n                                      do_handshake_on_connect=False)\n        self._add_io_state(old_state)\n        super(SSLIOStream, self)._handle_connect()\n\n    def read_from_fd(self):\n        if self._ssl_accepting:\n            # If the handshake hasn't finished yet, there can't be anything\n            # to read (attempting to read may or may not raise an exception\n            # depending on the SSL version)\n            return None\n        try:\n            # SSLSocket objects have both a read() and recv() method,\n            # while regular sockets only have recv().\n            # The recv() method blocks (at least in python 2.6) if it is\n            # called when there is nothing to read, so we have to use\n            # read() instead.\n            chunk = self.socket.read(self.read_chunk_size)\n        except ssl.SSLError as e:\n            # SSLError is a subclass of socket.error, so this except\n            # block must come first.\n            if e.args[0] == ssl.SSL_ERROR_WANT_READ:\n                return None\n            else:\n                raise\n        except socket.error as e:\n            if e.args[0] in _ERRNO_WOULDBLOCK:\n                return None\n            else:\n                raise\n        if not chunk:\n            self.close()\n            return None\n        return chunk\n\n\nclass PipeIOStream(BaseIOStream):\n    \"\"\"Pipe-based `IOStream` implementation.\n\n    The constructor takes an integer file descriptor (such as one returned\n    by `os.pipe`) rather than an open file object.  Pipes are generally\n    one-way, so a `PipeIOStream` can be used for reading or writing but not\n    both.\n    \"\"\"\n    def __init__(self, fd, *args, **kwargs):\n        self.fd = fd\n        _set_nonblocking(fd)\n        super(PipeIOStream, self).__init__(*args, **kwargs)\n\n    def fileno(self):\n        return self.fd\n\n    def close_fd(self):\n        os.close(self.fd)\n\n    def write_to_fd(self, data):\n        return os.write(self.fd, data)\n\n    def read_from_fd(self):\n        try:\n            chunk = os.read(self.fd, self.read_chunk_size)\n        except (IOError, OSError) as e:\n            if e.args[0] in _ERRNO_WOULDBLOCK:\n                return None\n            elif e.args[0] == errno.EBADF:\n                # If the writing half of a pipe is closed, select will\n                # report it as readable but reads will fail with EBADF.\n                self.close(exc_info=True)\n                return None\n            else:\n                raise\n        if not chunk:\n            self.close()\n            return None\n        return chunk\n\n\ndef _double_prefix(deque):\n    \"\"\"Grow by doubling, but don't split the second chunk just because the\n    first one is small.\n    \"\"\"\n    new_len = max(len(deque[0]) * 2,\n                  (len(deque[0]) + len(deque[1])))\n    _merge_prefix(deque, new_len)\n\n\ndef _merge_prefix(deque, size):\n    \"\"\"Replace the first entries in a deque of strings with a single\n    string of up to size bytes.\n\n    >>> d = collections.deque(['abc', 'de', 'fghi', 'j'])\n    >>> _merge_prefix(d, 5); print(d)\n    deque(['abcde', 'fghi', 'j'])\n\n    Strings will be split as necessary to reach the desired size.\n    >>> _merge_prefix(d, 7); print(d)\n    deque(['abcdefg', 'hi', 'j'])\n\n    >>> _merge_prefix(d, 3); print(d)\n    deque(['abc', 'defg', 'hi', 'j'])\n\n    >>> _merge_prefix(d, 100); print(d)\n    deque(['abcdefghij'])\n    \"\"\"\n    if len(deque) == 1 and len(deque[0]) <= size:\n        return\n    prefix = []\n    remaining = size\n    while deque and remaining > 0:\n        chunk = deque.popleft()\n        if len(chunk) > remaining:\n            deque.appendleft(chunk[remaining:])\n            chunk = chunk[:remaining]\n        prefix.append(chunk)\n        remaining -= len(chunk)\n    # This data structure normally just contains byte strings, but\n    # the unittest gets messy if it doesn't use the default str() type,\n    # so do the merge based on the type of data that's actually present.\n    if prefix:\n        deque.appendleft(type(prefix[0])().join(prefix))\n    if not deque:\n        deque.appendleft(b\"\")\n\n\ndef doctests():\n    import doctest\n    return doctest.DocTestSuite()\n"}
A user will ask you to solve a task. You should first draft your thinking process (inner monologue). Then, generate the solution.

Your response format must follow the template below:
<think>
Your thoughts or/and draft, like working through an exercise on scratch paper. Be as casual and as long as you want until you are confident to generate a correct solution.
</think>
<solution>
Final solution presented to the user.
</solution>
system
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]

**Close callback not invoked when using Future read interface**

**Description**
When using the Future-based read interface in `IOStream`, the `close_callback` is not triggered upon closing the client. This results in operations hanging or timing out because the callback never executes as expected.

**Example Code**
```python
server, client = self.make_iostream_pair()
closed = [False]

def close_callback():
    closed[0] = True
    self.stop()

server.set_close_callback(close_callback)

client.write(b'a')
future = server.read_bytes(1)
self.io_loop.add_future(future, self.stop)
result = self.wait().result()
print(result)  # Expected: b'a'
print(closed[0])  # Expected: False

client.close()
self.wait()
print(closed[0])  # Expected: True
```

**Expected Behavior**
After closing the client, the `close_callback` should be invoked, setting `closed[0]` to `True`. This ensures that any cleanup or follow-up actions tied to the callback are executed properly.

**Actual Behavior**
The `close_callback` is not called, leaving `closed[0]` as `False`. This causes the operation to hang and eventually timeout, as the expected callback execution does not occur.

[/ISSUE]
--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.

--- BEGIN FILE ---
```
### tornado/iostream.py
#!/usr/bin/env python
#
# Copyright 2009 Facebook
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

"""Utility classes to write to and read from non-blocking files and sockets.

Contents:

* `BaseIOStream`: Generic interface for reading and writing.
* `IOStream`: Implementation of BaseIOStream using non-blocking sockets.
* `SSLIOStream`: SSL-aware version of IOStream.
* `PipeIOStream`: Pipe-based IOStream implementation.
"""

from __future__ import absolute_import, division, print_function, with_statement

import collections
import errno
import numbers
import os
import socket
import ssl
import sys
import re

from tornado.concurrent import TracebackFuture
from tornado import ioloop
from tornado.log import gen_log, app_log
from tornado.netutil import ssl_wrap_socket, ssl_match_hostname, SSLCertificateError
from tornado import stack_context
from tornado.util import bytes_type

try:
    from tornado.platform.posix import _set_nonblocking
except ImportError:
    _set_nonblocking = None

# These errnos indicate that a non-blocking operation must be retried
# at a later time.  On most platforms they're the same value, but on
# some they differ.
_ERRNO_WOULDBLOCK = (errno.EWOULDBLOCK, errno.EAGAIN)

# These errnos indicate that a connection has been abruptly terminated.
# They should be caught and handled less noisily than other errors.
_ERRNO_CONNRESET = (errno.ECONNRESET, errno.ECONNABORTED, errno.EPIPE)


class StreamClosedError(IOError):
    """Exception raised by `IOStream` methods when the stream is closed.

    Note that the close callback is scheduled to run *after* other
    callbacks on the stream (to allow for buffered data to be processed),
    so you may see this error before you see the close callback.
    """
    pass


class BaseIOStream(object):
    """A utility class to write to and read from a non-blocking file or socket.

    We support a non-blocking ``write()`` and a family of ``read_*()`` methods.
    All of the methods take callbacks (since writing and reading are
    non-blocking and asynchronous).

    When a stream is closed due to an error, the IOStream's ``error``
    attribute contains the exception object.

    Subclasses must implement `fileno`, `close_fd`, `write_to_fd`,
    `read_from_fd`, and optionally `get_fd_error`.
    """
    def __init__(self, io_loop=None, max_buffer_size=None,
                 read_chunk_size=4096):
        self.io_loop = io_loop or ioloop.IOLoop.current()
        self.max_buffer_size = max_buffer_size or 104857600
        self.read_chunk_size = read_chunk_size
        self.error = None
        self._read_buffer = collections.deque()
        self._write_buffer = collections.deque()
        self._read_buffer_size = 0
        self._write_buffer_frozen = False
        self._read_delimiter = None
        self._read_regex = None
        self._read_bytes = None
        self._read_until_close = False
        self._read_callback = None
        self._read_future = None
        self._streaming_callback = None
        self._write_callback = None
        self._write_future = None
        self._close_callback = None
        self._connect_callback = None
        self._connect_future = None
        self._connecting = False
        self._state = None
        self._pending_callbacks = 0
        self._closed = False

    def fileno(self):
        """Returns the file descriptor for this stream."""
        raise NotImplementedError()

    def close_fd(self):
        """Closes the file underlying this stream.

        ``close_fd`` is called by `BaseIOStream` and should not be called
        elsewhere; other users should call `close` instead.
        """
        raise NotImplementedError()

    def write_to_fd(self, data):
        """Attempts to write ``data`` to the underlying file.

        Returns the number of bytes written.
        """
        raise NotImplementedError()

    def read_from_fd(self):
        """Attempts to read from the underlying file.

        Returns ``None`` if there was nothing to read (the socket
        returned `~errno.EWOULDBLOCK` or equivalent), otherwise
        returns the data.  When possible, should return no more than
        ``self.read_chunk_size`` bytes at a time.
        """
        raise NotImplementedError()

    def get_fd_error(self):
        """Returns information about any error on the underlying file.

        This method is called after the `.IOLoop` has signaled an error on the
        file descriptor, and should return an Exception (such as `socket.error`
        with additional information, or None if no such information is
        available.
        """
        return None

    def read_until_regex(self, regex, callback=None):
        """Run ``callback`` when we read the given regex pattern.

        The callback will get the data read (including the data that
        matched the regex and anything that came before it) as an argument.
        """
        future = self._set_read_callback(callback)
        self._read_regex = re.compile(regex)
        self._try_inline_read()
        return future

    def read_until(self, delimiter, callback=None):
        """Run ``callback`` when we read the given delimiter.

        The callback will get the data read (including the delimiter)
        as an argument.
        """
        future = self._set_read_callback(callback)
        self._read_delimiter = delimiter
        self._try_inline_read()
        return future

    def read_bytes(self, num_bytes, callback=None, streaming_callback=None):
        """Run callback when we read the given number of bytes.

        If a ``streaming_callback`` is given, it will be called with chunks
        of data as they become available, and the argument to the final
        ``callback`` will be empty.  Otherwise, the ``callback`` gets
        the data as an argument.
        """
        future = self._set_read_callback(callback)
        assert isinstance(num_bytes, numbers.Integral)
        self._read_bytes = num_bytes
        self._streaming_callback = stack_context.wrap(streaming_callback)
        self._try_inline_read()
        return future

    def read_until_close(self, callback=None, streaming_callback=None):
        """Reads all data from the socket until it is closed.

        If a ``streaming_callback`` is given, it will be called with chunks
        of data as they become available, and the argument to the final
        ``callback`` will be empty.  Otherwise, the ``callback`` gets the
        data as an argument.

        Subject to ``max_buffer_size`` limit from `IOStream` constructor if
        a ``streaming_callback`` is not used.
        """
        future = self._set_read_callback(callback)
        self._streaming_callback = stack_context.wrap(streaming_callback)
        if self.closed():
            if self._streaming_callback is not None:
                self._run_callback(self._streaming_callback,
                                   self._consume(self._read_buffer_size))
            self._run_read_callback(self._consume(self._read_buffer_size))
            return future
        self._read_until_close = True
        self._streaming_callback = stack_context.wrap(streaming_callback)
        self._try_inline_read()
        return future

    def write(self, data, callback=None):
        """Write the given data to this stream.

        If ``callback`` is given, we call it when all of the buffered write
        data has been successfully written to the stream. If there was
        previously buffered write data and an old write callback, that
        callback is simply overwritten with this new callback.
        """
        assert isinstance(data, bytes_type)
        self._check_closed()
        # We use bool(_write_buffer) as a proxy for write_buffer_size>0,
        # so never put empty strings in the buffer.
        if data:
            # Break up large contiguous strings before inserting them in the
            # write buffer, so we don't have to recopy the entire thing
            # as we slice off pieces to send to the socket.
            WRITE_BUFFER_CHUNK_SIZE = 128 * 1024
            for i in range(0, len(data), WRITE_BUFFER_CHUNK_SIZE):
                self._write_buffer.append(data[i:i + WRITE_BUFFER_CHUNK_SIZE])
        if callback is not None:
            self._write_callback = stack_context.wrap(callback)
            future = None
        else:
            future = self._write_future = TracebackFuture()
        if not self._connecting:
            self._handle_write()
            if self._write_buffer:
                self._add_io_state(self.io_loop.WRITE)
            self._maybe_add_error_listener()
        return future

    def set_close_callback(self, callback):
        """Call the given callback when the stream is closed."""
        self._close_callback = stack_context.wrap(callback)

    def close(self, exc_info=False):
        """Close this stream.

        If ``exc_info`` is true, set the ``error`` attribute to the current
        exception from `sys.exc_info` (or if ``exc_info`` is a tuple,
        use that instead of `sys.exc_info`).
        """
        if not self.closed():
            if exc_info:
                if not isinstance(exc_info, tuple):
                    exc_info = sys.exc_info()
                if any(exc_info):
                    self.error = exc_info[1]
            if self._read_until_close:
                if (self._streaming_callback is not None and
                        self._read_buffer_size):
                    self._run_callback(self._streaming_callback,
                                       self._consume(self._read_buffer_size))
                self._read_until_close = False
                self._run_read_callback(self._consume(self._read_buffer_size))
            if self._state is not None:
                self.io_loop.remove_handler(self.fileno())
                self._state = None
            self.close_fd()
            self._closed = True
        self._maybe_run_close_callback()

    def _maybe_run_close_callback(self):
        # If there are pending callbacks, don't run the close callback
        # until they're done (see _maybe_add_error_handler)
        if self.closed() and self._pending_callbacks == 0:
            futures = []
            if self._read_future is not None:
                futures.append(self._read_future)
                self._read_future = None
            if self._write_future is not None:
                futures.append(self._write_future)
                self._write_future = None
            if self._connect_future is not None:
                futures.append(self._connect_future)
                self._connect_future = None
            for future in futures:
                future.set_exception(StreamClosedError())
            if self._close_callback is not None:
                cb = self._close_callback
                self._close_callback = None
                self._run_callback(cb)
            # Delete any unfinished callbacks to break up reference cycles.
            self._read_callback = self._write_callback = None
            # Clear the buffers so they can be cleared immediately even
            # if the IOStream object is kept alive by a reference cycle.
            # TODO: Clear the read buffer too; it currently breaks some tests.
            self._write_buffer = None

    def reading(self):
        """Returns true if we are currently reading from the stream."""
        return self._read_callback is not None

    def writing(self):
        """Returns true if we are currently writing to the stream."""
        return bool(self._write_buffer)

    def closed(self):
        """Returns true if the stream has been closed."""
        return self._closed

    def set_nodelay(self, value):
        """Sets the no-delay flag for this stream.

        By default, data written to TCP streams may be held for a time
        to make the most efficient use of bandwidth (according to
        Nagle's algorithm).  The no-delay flag requests that data be
        written as soon as possible, even if doing so would consume
        additional bandwidth.

        This flag is currently defined only for TCP-based ``IOStreams``.

        .. versionadded:: 3.1
        """
        pass

    def _handle_events(self, fd, events):
        if self.closed():
            gen_log.warning("Got events for closed stream %s", fd)
            return
        try:
            if events & self.io_loop.READ:
                self._handle_read()
            if self.closed():
                return
            if events & self.io_loop.WRITE:
                if self._connecting:
                    self._handle_connect()
                self._handle_write()
            if self.closed():
                return
            if events & self.io_loop.ERROR:
                self.error = self.get_fd_error()
                # We may have queued up a user callback in _handle_read or
                # _handle_write, so don't close the IOStream until those
                # callbacks have had a chance to run.
                self.io_loop.add_callback(self.close)
                return
            state = self.io_loop.ERROR
            if self.reading():
                state |= self.io_loop.READ
            if self.writing():
                state |= self.io_loop.WRITE
            if state == self.io_loop.ERROR:
                state |= self.io_loop.READ
            if state != self._state:
                assert self._state is not None, \
                    "shouldn't happen: _handle_events without self._state"
                self._state = state
                self.io_loop.update_handler(self.fileno(), self._state)
        except Exception:
            gen_log.error("Uncaught exception, closing connection.",
                          exc_info=True)
            self.close(exc_info=True)
            raise

    def _run_callback(self, callback, *args):
        def wrapper():
            self._pending_callbacks -= 1
            try:
                callback(*args)
            except Exception:
                app_log.error("Uncaught exception, closing connection.",
                              exc_info=True)
                # Close the socket on an uncaught exception from a user callback
                # (It would eventually get closed when the socket object is
                # gc'd, but we don't want to rely on gc happening before we
                # run out of file descriptors)
                self.close(exc_info=True)
                # Re-raise the exception so that IOLoop.handle_callback_exception
                # can see it and log the error
                raise
            self._maybe_add_error_listener()
        # We schedule callbacks to be run on the next IOLoop iteration
        # rather than running them directly for several reasons:
        # * Prevents unbounded stack growth when a callback calls an
        #   IOLoop operation that immediately runs another callback
        # * Provides a predictable execution context for e.g.
        #   non-reentrant mutexes
        # * Ensures that the try/except in wrapper() is run outside
        #   of the application's StackContexts
        with stack_context.NullContext():
            # stack_context was already captured in callback, we don't need to
            # capture it again for IOStream's wrapper.  This is especially
            # important if the callback was pre-wrapped before entry to
            # IOStream (as in HTTPConnection._header_callback), as we could
            # capture and leak the wrong context here.
            self._pending_callbacks += 1
            self.io_loop.add_callback(wrapper)

    def _handle_read(self):
        try:
            try:
                # Pretend to have a pending callback so that an EOF in
                # _read_to_buffer doesn't trigger an immediate close
                # callback.  At the end of this method we'll either
                # estabilsh a real pending callback via
                # _read_from_buffer or run the close callback.
                #
                # We need two try statements here so that
                # pending_callbacks is decremented before the `except`
                # clause below (which calls `close` and does need to
                # trigger the callback)
                self._pending_callbacks += 1
                while not self.closed():
                    # Read from the socket until we get EWOULDBLOCK or equivalent.
                    # SSL sockets do some internal buffering, and if the data is
                    # sitting in the SSL object's buffer select() and friends
                    # can't see it; the only way to find out if it's there is to
                    # try to read it.
                    if self._read_to_buffer() == 0:
                        break
            finally:
                self._pending_callbacks -= 1
        except Exception:
            gen_log.warning("error on read", exc_info=True)
            self.close(exc_info=True)
            return
        if self._read_from_buffer():
            return
        else:
            self._maybe_run_close_callback()

    def _set_read_callback(self, callback):
        assert self._read_callback is None, "Already reading"
        assert self._read_future is None, "Already reading"
        if callback is not None:
            self._read_callback = stack_context.wrap(callback)
        else:
            self._read_future = TracebackFuture()
        return self._read_future

    def _run_read_callback(self, data):
        self._streaming_callback = None
        if self._read_future is not None:
            future = self._read_future
            self._read_future = None
            future.set_result(data)
        if self._read_callback is not None:
            callback = self._read_callback
            self._read_callback = None
            self._run_callback(callback, data)

    def _try_inline_read(self):
        """Attempt to complete the current read operation from buffered data.

        If the read can be completed without blocking, schedules the
        read callback on the next IOLoop iteration; otherwise starts
        listening for reads on the socket.
        """
        # See if we've already got the data from a previous read
        if self._read_from_buffer():
            return
        self._check_closed()
        try:
            try:
                # See comments in _handle_read about incrementing _pending_callbacks
                self._pending_callbacks += 1
                while not self.closed():
                    if self._read_to_buffer() == 0:
                        break
            finally:
                self._pending_callbacks -= 1
        except Exception:
            # If there was an in _read_to_buffer, we called close() already,
            # but couldn't run the close callback because of _pending_callbacks.
            # Before we escape from this function, run the close callback if
            # applicable.
            self._maybe_run_close_callback()
            raise
        if self._read_from_buffer():
            return
        self._maybe_add_error_listener()

    def _read_to_buffer(self):
        """Reads from the socket and appends the result to the read buffer.

        Returns the number of bytes read.  Returns 0 if there is nothing
        to read (i.e. the read returns EWOULDBLOCK or equivalent).  On
        error closes the socket and raises an exception.
        """
        try:
            chunk = self.read_from_fd()
        except (socket.error, IOError, OSError) as e:
            # ssl.SSLError is a subclass of socket.error
            if e.args[0] in _ERRNO_CONNRESET:
                # Treat ECONNRESET as a connection close rather than
                # an error to minimize log spam  (the exception will
                # be available on self.error for apps that care).
                self.close(exc_info=True)
                return
            self.close(exc_info=True)
            raise
        if chunk is None:
            return 0
        self._read_buffer.append(chunk)
        self._read_buffer_size += len(chunk)
        if self._read_buffer_size >= self.max_buffer_size:
            gen_log.error("Reached maximum read buffer size")
            self.close()
            raise IOError("Reached maximum read buffer size")
        return len(chunk)

    def _read_from_buffer(self):
        """Attempts to complete the currently-pending read from the buffer.

        Returns True if the read was completed.
        """
        if self._streaming_callback is not None and self._read_buffer_size:
            bytes_to_consume = self._read_buffer_size
            if self._read_bytes is not None:
                bytes_to_consume = min(self._read_bytes, bytes_to_consume)
                self._read_bytes -= bytes_to_consume
            self._run_callback(self._streaming_callback,
                               self._consume(bytes_to_consume))
        if self._read_bytes is not None and self._read_buffer_size >= self._read_bytes:
            num_bytes = self._read_bytes
            self._read_bytes = None
            self._run_read_callback(self._consume(num_bytes))
            return True
        elif self._read_delimiter is not None:
            # Multi-byte delimiters (e.g. '\r\n') may straddle two
            # chunks in the read buffer, so we can't easily find them
            # without collapsing the buffer.  However, since protocols
            # using delimited reads (as opposed to reads of a known
            # length) tend to be "line" oriented, the delimiter is likely
            # to be in the first few chunks.  Merge the buffer gradually
            # since large merges are relatively expensive and get undone in
            # consume().
            if self._read_buffer:
                while True:
                    loc = self._read_buffer[0].find(self._read_delimiter)
                    if loc != -1:
                        delimiter_len = len(self._read_delimiter)
                        self._read_delimiter = None
                        self._run_read_callback(
                            self._consume(loc + delimiter_len))
                        return True
                    if len(self._read_buffer) == 1:
                        break
                    _double_prefix(self._read_buffer)
        elif self._read_regex is not None:
            if self._read_buffer:
                while True:
                    m = self._read_regex.search(self._read_buffer[0])
                    if m is not None:
                        self._read_regex = None
                        self._run_read_callback(self._consume(m.end()))
                        return True
                    if len(self._read_buffer) == 1:
                        break
                    _double_prefix(self._read_buffer)
        return False

    def _handle_write(self):
        while self._write_buffer:
            try:
                if not self._write_buffer_frozen:
                    # On windows, socket.send blows up if given a
                    # write buffer that's too large, instead of just
                    # returning the number of bytes it was able to
                    # process.  Therefore we must not call socket.send
                    # with more than 128KB at a time.
                    _merge_prefix(self._write_buffer, 128 * 1024)
                num_bytes = self.write_to_fd(self._write_buffer[0])
                if num_bytes == 0:
                    # With OpenSSL, if we couldn't write the entire buffer,
                    # the very same string object must be used on the
                    # next call to send.  Therefore we suppress
                    # merging the write buffer after an incomplete send.
                    # A cleaner solution would be to set
                    # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, but this is
                    # not yet accessible from python
                    # (http://bugs.python.org/issue8240)
                    self._write_buffer_frozen = True
                    break
                self._write_buffer_frozen = False
                _merge_prefix(self._write_buffer, num_bytes)
                self._write_buffer.popleft()
            except (socket.error, IOError, OSError) as e:
                if e.args[0] in _ERRNO_WOULDBLOCK:
                    self._write_buffer_frozen = True
                    break
                else:
                    if e.args[0] not in _ERRNO_CONNRESET:
                        # Broken pipe errors are usually caused by connection
                        # reset, and its better to not log EPIPE errors to
                        # minimize log spam
                        gen_log.warning("Write error on %s: %s",
                                        self.fileno(), e)
                    self.close(exc_info=True)
                    return
        if not self._write_buffer:
            if self._write_callback:
                callback = self._write_callback
                self._write_callback = None
                self._run_callback(callback)
            if self._write_future:
                future = self._write_future
                self._write_future = None
                future.set_result(None)

    def _consume(self, loc):
        if loc == 0:
            return b""
        _merge_prefix(self._read_buffer, loc)
        self._read_buffer_size -= loc
        return self._read_buffer.popleft()

    def _check_closed(self):
        if self.closed():
            raise StreamClosedError("Stream is closed")

    def _maybe_add_error_listener(self):
        if self._state is None and self._pending_callbacks == 0:
            if self.closed():
                self._maybe_run_close_callback()
            else:
                self._add_io_state(ioloop.IOLoop.READ)

    def _add_io_state(self, state):
        """Adds `state` (IOLoop.{READ,WRITE} flags) to our event handler.

        Implementation notes: Reads and writes have a fast path and a
        slow path.  The fast path reads synchronously from socket
        buffers, while the slow path uses `_add_io_state` to schedule
        an IOLoop callback.  Note that in both cases, the callback is
        run asynchronously with `_run_callback`.

        To detect closed connections, we must have called
        `_add_io_state` at some point, but we want to delay this as
        much as possible so we don't have to set an `IOLoop.ERROR`
        listener that will be overwritten by the next slow-path
        operation.  As long as there are callbacks scheduled for
        fast-path ops, those callbacks may do more reads.
        If a sequence of fast-path ops do not end in a slow-path op,
        (e.g. for an @asynchronous long-poll request), we must add
        the error handler.  This is done in `_run_callback` and `write`
        (since the write callback is optional so we can have a
        fast-path write with no `_run_callback`)
        """
        if self.closed():
            # connection has been closed, so there can be no future events
            return
        if self._state is None:
            self._state = ioloop.IOLoop.ERROR | state
            with stack_context.NullContext():
                self.io_loop.add_handler(
                    self.fileno(), self._handle_events, self._state)
        elif not self._state & state:
            self._state = self._state | state
            self.io_loop.update_handler(self.fileno(), self._state)


class IOStream(BaseIOStream):
    r"""Socket-based `IOStream` implementation.

    This class supports the read and write methods from `BaseIOStream`
    plus a `connect` method.

    The ``socket`` parameter may either be connected or unconnected.
    For server operations the socket is the result of calling
    `socket.accept <socket.socket.accept>`.  For client operations the
    socket is created with `socket.socket`, and may either be
    connected before passing it to the `IOStream` or connected with
    `IOStream.connect`.

    A very simple (and broken) HTTP client using this class::

        import tornado.ioloop
        import tornado.iostream
        import socket

        def send_request():
            stream.write(b"GET / HTTP/1.0\r\nHost: friendfeed.com\r\n\r\n")
            stream.read_until(b"\r\n\r\n", on_headers)

        def on_headers(data):
            headers = {}
            for line in data.split(b"\r\n"):
               parts = line.split(b":")
               if len(parts) == 2:
                   headers[parts[0].strip()] = parts[1].strip()
            stream.read_bytes(int(headers[b"Content-Length"]), on_body)

        def on_body(data):
            print data
            stream.close()
            tornado.ioloop.IOLoop.instance().stop()

        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
        stream = tornado.iostream.IOStream(s)
        stream.connect(("friendfeed.com", 80), send_request)
        tornado.ioloop.IOLoop.instance().start()
    """
    def __init__(self, socket, *args, **kwargs):
        self.socket = socket
        self.socket.setblocking(False)
        super(IOStream, self).__init__(*args, **kwargs)

    def fileno(self):
        return self.socket

    def close_fd(self):
        self.socket.close()
        self.socket = None

    def get_fd_error(self):
        errno = self.socket.getsockopt(socket.SOL_SOCKET,
                                       socket.SO_ERROR)
        return socket.error(errno, os.strerror(errno))

    def read_from_fd(self):
        try:
            chunk = self.socket.recv(self.read_chunk_size)
        except socket.error as e:
            if e.args[0] in _ERRNO_WOULDBLOCK:
                return None
            else:
                raise
        if not chunk:
            self.close()
            return None
        return chunk

    def write_to_fd(self, data):
        return self.socket.send(data)

    def connect(self, address, callback=None, server_hostname=None):
        """Connects the socket to a remote address without blocking.

        May only be called if the socket passed to the constructor was
        not previously connected.  The address parameter is in the
        same format as for `socket.connect <socket.socket.connect>`,
        i.e. a ``(host, port)`` tuple.  If ``callback`` is specified,
        it will be called when the connection is completed.

        If specified, the ``server_hostname`` parameter will be used
        in SSL connections for certificate validation (if requested in
        the ``ssl_options``) and SNI (if supported; requires
        Python 3.2+).

        Note that it is safe to call `IOStream.write
        <BaseIOStream.write>` while the connection is pending, in
        which case the data will be written as soon as the connection
        is ready.  Calling `IOStream` read methods before the socket is
        connected works on some platforms but is non-portable.
        """
        self._connecting = True
        try:
            self.socket.connect(address)
        except socket.error as e:
            # In non-blocking mode we expect connect() to raise an
            # exception with EINPROGRESS or EWOULDBLOCK.
            #
            # On freebsd, other errors such as ECONNREFUSED may be
            # returned immediately when attempting to connect to
            # localhost, so handle them the same way as an error
            # reported later in _handle_connect.
            if (e.args[0] != errno.EINPROGRESS and
                    e.args[0] not in _ERRNO_WOULDBLOCK):
                gen_log.warning("Connect error on fd %s: %s",
                                self.socket.fileno(), e)
                self.close(exc_info=True)
                return
        if callback is not None:
            self._connect_callback = stack_context.wrap(callback)
            future = None
        else:
            future = self._connect_future = TracebackFuture()
        self._add_io_state(self.io_loop.WRITE)
        return future

    def _handle_connect(self):
        err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
        if err != 0:
            self.error = socket.error(err, os.strerror(err))
            # IOLoop implementations may vary: some of them return
            # an error state before the socket becomes writable, so
            # in that case a connection failure would be handled by the
            # error path in _handle_events instead of here.
            gen_log.warning("Connect error on fd %s: %s",
                            self.socket.fileno(), errno.errorcode[err])
            self.close()
            return
        if self._connect_callback is not None:
            callback = self._connect_callback
            self._connect_callback = None
            self._run_callback(callback)
        if self._connect_future is not None:
            future = self._connect_future
            self._connect_future = None
            future.set_result(None)
        self._connecting = False

    def set_nodelay(self, value):
        if (self.socket is not None and
                self.socket.family in (socket.AF_INET, socket.AF_INET6)):
            try:
                self.socket.setsockopt(socket.IPPROTO_TCP,
                                       socket.TCP_NODELAY, 1 if value else 0)
            except socket.error as e:
                # Sometimes setsockopt will fail if the socket is closed
                # at the wrong time.  This can happen with HTTPServer
                # resetting the value to false between requests.
                if e.errno not in (errno.EINVAL, errno.ECONNRESET):
                    raise


class SSLIOStream(IOStream):
    """A utility class to write to and read from a non-blocking SSL socket.

    If the socket passed to the constructor is already connected,
    it should be wrapped with::

        ssl.wrap_socket(sock, do_handshake_on_connect=False, **kwargs)

    before constructing the `SSLIOStream`.  Unconnected sockets will be
    wrapped when `IOStream.connect` is finished.
    """
    def __init__(self, *args, **kwargs):
        """The ``ssl_options`` keyword argument may either be a dictionary
        of keywords arguments for `ssl.wrap_socket`, or an `ssl.SSLContext`
        object.
        """
        self._ssl_options = kwargs.pop('ssl_options', {})
        super(SSLIOStream, self).__init__(*args, **kwargs)
        self._ssl_accepting = True
        self._handshake_reading = False
        self._handshake_writing = False
        self._ssl_connect_callback = None
        self._server_hostname = None

        # If the socket is already connected, attempt to start the handshake.
        try:
            self.socket.getpeername()
        except socket.error:
            pass
        else:
            # Indirectly start the handshake, which will run on the next
            # IOLoop iteration and then the real IO state will be set in
            # _handle_events.
            self._add_io_state(self.io_loop.WRITE)

    def reading(self):
        return self._handshake_reading or super(SSLIOStream, self).reading()

    def writing(self):
        return self._handshake_writing or super(SSLIOStream, self).writing()

    def _do_ssl_handshake(self):
        # Based on code from test_ssl.py in the python stdlib
        try:
            self._handshake_reading = False
            self._handshake_writing = False
            self.socket.do_handshake()
        except ssl.SSLError as err:
            if err.args[0] == ssl.SSL_ERROR_WANT_READ:
                self._handshake_reading = True
                return
            elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
                self._handshake_writing = True
                return
            elif err.args[0] in (ssl.SSL_ERROR_EOF,
                                 ssl.SSL_ERROR_ZERO_RETURN):
                return self.close(exc_info=True)
            elif err.args[0] == ssl.SSL_ERROR_SSL:
                try:
                    peer = self.socket.getpeername()
                except Exception:
                    peer = '(not connected)'
                gen_log.warning("SSL Error on %s %s: %s",
                                self.socket.fileno(), peer, err)
                return self.close(exc_info=True)
            raise
        except socket.error as err:
            if err.args[0] in _ERRNO_CONNRESET:
                return self.close(exc_info=True)
        except AttributeError:
            # On Linux, if the connection was reset before the call to
            # wrap_socket, do_handshake will fail with an
            # AttributeError.
            return self.close(exc_info=True)
        else:
            self._ssl_accepting = False
            if not self._verify_cert(self.socket.getpeercert()):
                self.close()
                return
            if self._ssl_connect_callback is not None:
                callback = self._ssl_connect_callback
                self._ssl_connect_callback = None
                self._run_callback(callback)

    def _verify_cert(self, peercert):
        """Returns True if peercert is valid according to the configured
        validation mode and hostname.

        The ssl handshake already tested the certificate for a valid
        CA signature; the only thing that remains is to check
        the hostname.
        """
        if isinstance(self._ssl_options, dict):
            verify_mode = self._ssl_options.get('cert_reqs', ssl.CERT_NONE)
        elif isinstance(self._ssl_options, ssl.SSLContext):
            verify_mode = self._ssl_options.verify_mode
        assert verify_mode in (ssl.CERT_NONE, ssl.CERT_REQUIRED, ssl.CERT_OPTIONAL)
        if verify_mode == ssl.CERT_NONE or self._server_hostname is None:
            return True
        cert = self.socket.getpeercert()
        if cert is None and verify_mode == ssl.CERT_REQUIRED:
            gen_log.warning("No SSL certificate given")
            return False
        try:
            ssl_match_hostname(peercert, self._server_hostname)
        except SSLCertificateError:
            gen_log.warning("Invalid SSL certificate", exc_info=True)
            return False
        else:
            return True

    def _handle_read(self):
        if self._ssl_accepting:
            self._do_ssl_handshake()
            return
        super(SSLIOStream, self)._handle_read()

    def _handle_write(self):
        if self._ssl_accepting:
            self._do_ssl_handshake()
            return
        super(SSLIOStream, self)._handle_write()

    def connect(self, address, callback=None, server_hostname=None):
        # Save the user's callback and run it after the ssl handshake
        # has completed.
        self._ssl_connect_callback = stack_context.wrap(callback)
        self._server_hostname = server_hostname
        # Note: Since we don't pass our callback argument along to
        # super.connect(), this will always return a Future.
        # This is harmless, but a bit less efficient than it could be.
        return super(SSLIOStream, self).connect(address, callback=None)

    def _handle_connect(self):
        # When the connection is complete, wrap the socket for SSL
        # traffic.  Note that we do this by overriding _handle_connect
        # instead of by passing a callback to super().connect because
        # user callbacks are enqueued asynchronously on the IOLoop,
        # but since _handle_events calls _handle_connect immediately
        # followed by _handle_write we need this to be synchronous.
        #
        # The IOLoop will get confused if we swap out self.socket while the
        # fd is registered, so remove it now and re-register after
        # wrap_socket().
        self.io_loop.remove_handler(self.socket)
        old_state = self._state
        self._state = None
        self.socket = ssl_wrap_socket(self.socket, self._ssl_options,
                                      server_hostname=self._server_hostname,
                                      do_handshake_on_connect=False)
        self._add_io_state(old_state)
        super(SSLIOStream, self)._handle_connect()

    def read_from_fd(self):
        if self._ssl_accepting:
            # If the handshake hasn't finished yet, there can't be anything
            # to read (attempting to read may or may not raise an exception
            # depending on the SSL version)
            return None
        try:
            # SSLSocket objects have both a read() and recv() method,
            # while regular sockets only have recv().
            # The recv() method blocks (at least in python 2.6) if it is
            # called when there is nothing to read, so we have to use
            # read() instead.
            chunk = self.socket.read(self.read_chunk_size)
        except ssl.SSLError as e:
            # SSLError is a subclass of socket.error, so this except
            # block must come first.
            if e.args[0] == ssl.SSL_ERROR_WANT_READ:
                return None
            else:
                raise
        except socket.error as e:
            if e.args[0] in _ERRNO_WOULDBLOCK:
                return None
            else:
                raise
        if not chunk:
            self.close()
            return None
        return chunk


class PipeIOStream(BaseIOStream):
    """Pipe-based `IOStream` implementation.

    The constructor takes an integer file descriptor (such as one returned
    by `os.pipe`) rather than an open file object.  Pipes are generally
    one-way, so a `PipeIOStream` can be used for reading or writing but not
    both.
    """
    def __init__(self, fd, *args, **kwargs):
        self.fd = fd
        _set_nonblocking(fd)
        super(PipeIOStream, self).__init__(*args, **kwargs)

    def fileno(self):
        return self.fd

    def close_fd(self):
        os.close(self.fd)

    def write_to_fd(self, data):
        return os.write(self.fd, data)

    def read_from_fd(self):
        try:
            chunk = os.read(self.fd, self.read_chunk_size)
        except (IOError, OSError) as e:
            if e.args[0] in _ERRNO_WOULDBLOCK:
                return None
            elif e.args[0] == errno.EBADF:
                # If the writing half of a pipe is closed, select will
                # report it as readable but reads will fail with EBADF.
                self.close(exc_info=True)
                return None
            else:
                raise
        if not chunk:
            self.close()
            return None
        return chunk


def _double_prefix(deque):
    """Grow by doubling, but don't split the second chunk just because the
    first one is small.
    """
    new_len = max(len(deque[0]) * 2,
                  (len(deque[0]) + len(deque[1])))
    _merge_prefix(deque, new_len)


def _merge_prefix(deque, size):
    """Replace the first entries in a deque of strings with a single
    string of up to size bytes.

    >>> d = collections.deque(['abc', 'de', 'fghi', 'j'])
    >>> _merge_prefix(d, 5); print(d)
    deque(['abcde', 'fghi', 'j'])

    Strings will be split as necessary to reach the desired size.
    >>> _merge_prefix(d, 7); print(d)
    deque(['abcdefg', 'hi', 'j'])

    >>> _merge_prefix(d, 3); print(d)
    deque(['abc', 'defg', 'hi', 'j'])

    >>> _merge_prefix(d, 100); print(d)
    deque(['abcdefghij'])
    """
    if len(deque) == 1 and len(deque[0]) <= size:
        return
    prefix = []
    remaining = size
    while deque and remaining > 0:
        chunk = deque.popleft()
        if len(chunk) > remaining:
            deque.appendleft(chunk[remaining:])
            chunk = chunk[:remaining]
        prefix.append(chunk)
        remaining -= len(chunk)
    # This data structure normally just contains byte strings, but
    # the unittest gets messy if it doesn't use the default str() type,
    # so do the merge based on the type of data that's actually present.
    if prefix:
        deque.appendleft(type(prefix[0])().join(prefix))
    if not deque:
        deque.appendleft(b"")


def doctests():
    import doctest
    return doctest.DocTestSuite()

```
--- END FILE ---

Please first localize the bug based on the issue statement, and then generate *SEARCH/REPLACE* edits to fix the issue.

Every *SEARCH/REPLACE* edit must use this format:
1. The file path
2. The start of search block: <<<<<<< SEARCH
3. A contiguous chunk of lines to search for in the existing source code
4. The dividing line: =======
5. The lines to replace into the source code
6. The end of the replace block: >>>>>>> REPLACE

Here is an example:

```python
### mathweb/flask/app.py
<<<<<<< SEARCH
from flask import Flask
=======
import math
from flask import Flask
>>>>>>> REPLACE
```
</solution>

Please note that the *SEARCH/REPLACE* edit REQUIRES PROPER INDENTATION. If you would like to add the line '        print(x)', you must fully write that out, with all those spaces before the code!
Wrap each *SEARCH/REPLACE* edit in a code block as shown in the example above. If you have multiple *SEARCH/REPLACE* edits, use a separate code block for each one.
user