# Path: server/websockets/exceptions.py
# class ConnectionClosed(InvalidState):
#     """
#     Exception raised when trying to read or write on a closed connection.
# 
#     Provides the connection close code and reason in its ``code`` and
#     ``reason`` attributes respectively.
# 
#     """
#     def __init__(self, code, reason):
#         self.code = code
#         self.reason = reason
#         message = 'WebSocket connection is closed: '
#         message += 'code = {}, '.format(code) if code else 'no code, '
#         message += 'reason = {}.'.format(reason) if reason else 'no reason.'
#         super().__init__(message)
# 
# class InvalidHandshake(Exception):
#     """
#     Exception raised when a handshake request or response is invalid.
# 
#     """
# 
# Path: server/websockets/http.py
# USER_AGENT = ' '.join((
#     'Python/{}'.format(sys.version[:3]),
#     'websockets/{}'.format(websockets_version),
# ))
# 
# @asyncio.coroutine
# def read_response(stream):
#     """
#     Read an HTTP/1.1 response from ``stream``.
# 
#     Return ``(status, headers)`` where ``status`` is a :class:`int` and
#     ``headers`` is a :class:`~email.message.Message`.
# 
#     Raise an exception if the request isn't well formatted.
# 
#     The response is assumed not to contain a body.
# 
#     """
#     status_line, headers = yield from read_message(stream)
#     version, status, reason = status_line[:-2].decode().split(None, 2)
#     if version != 'HTTP/1.1':
#         raise ValueError("Unsupported HTTP version")
#     return int(status), headers


import asyncio
import logging
import os
import ssl
import unittest
import unittest.mock
from .client import *
from .exceptions import ConnectionClosed, InvalidHandshake
from .http import USER_AGENT, read_response
from .server import *
    from .py35.client_server import ClientServerContextManager
    @unittest.mock.patch.object(WebSocketClientProtocol, 'handshake')
    def test_client_closes_connection_before_handshake(self, handshake):
        self.start_server()
        self.start_client()
        # We have mocked the handshake() method to prevent the client from
        # performing the opening handshake. Force it to close the connection.
        self.loop.run_until_complete(self.client.close_connection(force=True))
        self.stop_client()
        # The server should stop properly anyway. It used to hang because the
        # worker handling the connection was waiting for the opening handshake.
        self.stop_server()

    @unittest.mock.patch('websockets.server.read_request')
    def test_server_shuts_down_during_opening_handshake(self, _read_request):
        _read_request.side_effect = asyncio.CancelledError

        self.start_server()
        self.server.closing = True
        with self.assertRaises(InvalidHandshake) as raised:
            self.start_client()
        self.stop_server()

        # Opening handshake fails with 503 Service Unavailable
        self.assertEqual(str(raised.exception), "Bad status code: 503")

    def test_server_shuts_down_during_connection_handling(self):
        self.start_server()
        self.start_client()

        self.server.close()

# Path: server/websockets/exceptions.py
# class ConnectionClosed(InvalidState):
#     """
#     Exception raised when trying to read or write on a closed connection.
# 
#     Provides the connection close code and reason in its ``code`` and
#     ``reason`` attributes respectively.
# 
#     """
#     def __init__(self, code, reason):
#         self.code = code
#         self.reason = reason
#         message = 'WebSocket connection is closed: '
#         message += 'code = {}, '.format(code) if code else 'no code, '
#         message += 'reason = {}.'.format(reason) if reason else 'no reason.'
#         super().__init__(message)
# 
# class InvalidHandshake(Exception):
#     """
#     Exception raised when a handshake request or response is invalid.
# 
#     """
# 
# Path: server/websockets/http.py
# USER_AGENT = ' '.join((
#     'Python/{}'.format(sys.version[:3]),
#     'websockets/{}'.format(websockets_version),
# ))
# 
# @asyncio.coroutine
# def read_response(stream):
#     """
#     Read an HTTP/1.1 response from ``stream``.
# 
#     Return ``(status, headers)`` where ``status`` is a :class:`int` and
#     ``headers`` is a :class:`~email.message.Message`.
# 
#     Raise an exception if the request isn't well formatted.
# 
#     The response is assumed not to contain a body.
# 
#     """
#     status_line, headers = yield from read_message(stream)
#     version, status, reason = status_line[:-2].decode().split(None, 2)
#     if version != 'HTTP/1.1':
#         raise ValueError("Unsupported HTTP version")
#     return int(status), headers


# Path: server/websockets/test_client_server.py
import asyncio
import logging
import os
import ssl
import unittest
import unittest.mock
from .client import *
from .exceptions import ConnectionClosed, InvalidHandshake
from .http import USER_AGENT, read_response
from .server import *
    from .py35.client_server import ClientServerContextManager

    @unittest.mock.patch.object(WebSocketClientProtocol, 'handshake')
    def test_client_closes_connection_before_handshake(self, handshake):
        self.start_server()
        self.start_client()
        # We have mocked the handshake() method to prevent the client from
        # performing the opening handshake. Force it to close the connection.
        self.loop.run_until_complete(self.client.close_connection(force=True))
        self.stop_client()
        # The server should stop properly anyway. It used to hang because the
        # worker handling the connection was waiting for the opening handshake.
        self.stop_server()

    @unittest.mock.patch('websockets.server.read_request')
    def test_server_shuts_down_during_opening_handshake(self, _read_request):
        _read_request.side_effect = asyncio.CancelledError

        self.start_server()
        self.server.closing = True
        with self.assertRaises(InvalidHandshake) as raised:
            self.start_client()
        self.stop_server()

        # Opening handshake fails with 503 Service Unavailable
        self.assertEqual(str(raised.exception), "Bad status code: 503")

    def test_server_shuts_down_during_connection_handling(self):
        self.start_server()
        self.start_client()

        self.server.close()

        with self.assertRaises(ConnectionClosed):