Ejemplo n.º 1
0
class TestTwistedTCPServer(TestAbstractServer):
    config = ServerConfig("somehost", 12345)
    app = SocketGameApplication(config)

    def setUp(self):
        # super().setUp()
        self.server = TwistedTCPServer(self.config, self.app)

    def test_init(self):
        super().test_init()

        self.assertIsNone(TwistedTCPServer.factory)
        self.assertIsInstance(self.server.factory, ServerFactory)
        self.assertEqual(self.server.config, self.config)
        self.assertEqual(self.server.factory.config, self.config)
        self.assertEqual(self.server.factory.protocol, TwistedHandler)
        self.assertEqual(self.server.factory.protocol_factory,
                         self.server.protocol_factory)

    def test_init_default(self):
        with self.assertRaises(Exception):
            TwistedTCPServer(None)

    def test_dispose(self):
        factory = self.server.factory

        super().test_dispose()

        self.assertIsNone(self.server.factory)
        self.assertIsNone(factory.config)
        self.assertIsNone(factory.protocol)
        self.assertIsNone(factory.protocol_factory)

    def test_start(self, server_mock=None):
        reactor.listenTCP = Mock()
        reactor.run = Mock()

        self.server.start()
        # Should skip others without errors
        self.server.start()
        self.server.start()

        reactor.listenTCP.assert_called_once_with(12345, self.server.factory)
        reactor.run.assert_called_once()

    def test_stop(self):
        reactor.stop = Mock()

        self.server.started = True

        self.server.stop()
        # Should skip others without errors
        self.server.stop()
        self.server.stop()

        reactor.stop.assert_not_called()
Ejemplo n.º 2
0
    def setUp(self):
        super().setUp()

        self.server_app = SocketGameApplication(self.server_config, self.server_class)
        self.start_server(self.server_app)

        for i in range(self.CLIENT_COUNT):
            credentials = {
                "user_id": str(i + 1),
                "social_id": str(i + 1001),
                "access_token": "qwertyuiopasdfghjklzxcvbnm" + str(i + 1),
                "auth_sig": TestServerSystem.make_auth_sig(str(i + 1), 
                                                           "qwertyuiopasdfghjklzxcvbnm" + str(i + 1), 
                                                           "tyuiop12345"),
                "backend": "fb_local"
            }
            client = self.client_class(self.client_config, credentials)
            self.clients.append(client)
            self.clients.append(client)
Ejemplo n.º 3
0
class TestTwistedHandler(TestCase):
    config = ServerConfig("somehost", 12345)
    config.DELIMITER = b"[MYEND]"
    config.protocol_class = Protocol
    app = SocketGameApplication(config)

    def setUp(self):
        super().setUp()
        self.handler = TwistedHandler()
        self.handler.factory = ServerFactory()
        self.handler.factory.config = self.config
        self.handler.factory.protocol_factory = ProtocolFactory(
            self.config, self.app)
        self.handler.transport = MagicMock(
            **{"getPeer.return_value": Mock(host="myhost", port=1234)})

    def test_lifetime(self):
        # connectionMade
        self.assertEqual(self.handler.delimiter, b"\x00")

        self.handler.connectionMade()

        self.assertEqual(self.handler.delimiter, b"[MYEND]")
        protocol = self.handler.protocol
        self.assertIsInstance(protocol, Protocol)
        self.assertEqual(protocol.send_bytes_method, self.handler.sendLine)
        self.assertEqual(protocol.close_connection_method,
                         self.handler.transport.loseConnection)
        self.assertEqual(protocol.config, self.config)
        self.assertEqual(protocol.address, ("myhost", 1234))

        # rawDataReceived: check no exception
        self.handler.rawDataReceived(None)

        # lineReceived
        protocol.process_bytes_list = Mock()

        self.handler.lineReceived("my||data||line##")

        self.assertEqual(self.handler.protocol, protocol)
        protocol.process_bytes_list.assert_called_once_with(
            ("my||data||line##", ))

        # connectionLost
        protocol.dispose = Mock(side_effect=protocol.dispose)

        self.handler.connectionLost()

        protocol.dispose.assert_called_once()
        self.assertIsNone(self.handler.protocol)
Ejemplo n.º 4
0
class TestProtocolFactory(TestCase):
    config = ServerConfig(protocol_class=ServerProtocol)
    app = SocketGameApplication(config)

    def setUp(self):
        super().setUp()
        self.protocol_factory = ProtocolFactory(self.config, self.app)

    def test_dispose(self):
        self.assertIsNotNone(self.protocol_factory.config)
        self.assertIsNotNone(self.protocol_factory.app)
        self.assertIsNotNone(self.protocol_factory.protocol_class)

        self.protocol_factory.dispose()

        self.assertIsNone(self.protocol_factory.config)
        self.assertIsNone(self.protocol_factory.app)
        self.assertIsNone(self.protocol_factory.protocol_class)

    def test_create(self):
        send_bytes_method, close_connection_method, address = Mock(), Mock(
        ), Mock()
        self.protocol_factory.protocol_class = protocol_class = Mock()

        self.protocol_factory.create(send_bytes_method,
                                     close_connection_method, address)

        protocol_class.assert_called_once_with(send_bytes_method,
                                               close_connection_method,
                                               address, self.config, self.app)

    def test_create_real(self):
        send_bytes_method, close_connection_method, address = Mock(), Mock(
        ), Mock()
        self.protocol_factory.protocol_class = Protocol

        protocol = self.protocol_factory.create(send_bytes_method,
                                                close_connection_method,
                                                address)

        self.assertIsInstance(protocol, Protocol)
        self.assertEqual(protocol.send_bytes_method, send_bytes_method)
        self.assertEqual(protocol.close_connection_method,
                         close_connection_method)
        self.assertEqual(protocol.config, self.config)
        # self.assertEqual(protocol.app, self.app)
        self.assertEqual(protocol.address, address)
Ejemplo n.º 5
0
class TestAbstractServer(TestCase):
    config = ServerConfig("somehost", 12345, Protocol)
    app = SocketGameApplication(config)

    def setUp(self):
        super().setUp()
        self.server = AbstractServer(self.config, self.app)

    def test_init(self):
        self.assertEqual(self.server.config, self.config)
        self.assertEqual(self.server.protocol_factory.config, self.config)
        self.assertEqual(self.server.protocol_factory.app, self.app)

    def test_init_default(self):
        with self.assertRaises(Exception):
            self.server = AbstractServer(None)

    def test_dispose(self):
        self.server.stop = Mock()
        self.server.protocol_factory.dispose = factory_dispose = Mock(
            side_effect=self.server.protocol_factory.dispose)

        self.server.dispose()

        self.server.stop.assert_called_once()
        factory_dispose.assert_called_once()
        self.assertIsNone(self.server.config)
        self.assertIsNone(self.server.protocol_factory)

    def test_start(self, server_mock=None):
        # (NotImplemented is unavailable)
        with self.assertRaises(Exception):
            self.server.start()

    def test_stop(self):
        # (NotImplemented is unavailable)
        with self.assertRaises(Exception):
            self.server.stop()
Ejemplo n.º 6
0
except ImportError:
    import sys
    # Link libraries (to launch from command line console)
    sys.path.append("../../library_server/python/")
    import napalm

from napalm.utils.parsing_util import get_command_line_param
from napalm.core import SocketGameApplication
from napalm.play.poker.lobby import PokerLobbyModel
from napalm.socket.server import NonBlockingTCPServer, ThreadedTCPServer, TwistedTCPServer

if __name__ == "__main__":
    # Get params from command line (sys.argv)
    lobby_id = get_command_line_param("-server-id", 1)
    data_dir_path = get_command_line_param("-data-path")  # or "../server_data"
    is_twisted = get_command_line_param("-twisted")
    is_non_blocking = get_command_line_param("-non-blocking")
    is_no_restore = get_command_line_param("-no-restore")

    # Config play and server
    server_config = PokerLobbyModel(lobby_id=lobby_id, data_dir_path=data_dir_path)
    server_config.napalm_secret = "myrandomforsocketserverSnJdG6dDZq6Os3i6iilo"
    if is_no_restore:
        server_config.save_lobby_state_enabled = False

    server_class = TwistedTCPServer if is_twisted else (NonBlockingTCPServer if is_non_blocking else ThreadedTCPServer)

    # Create and start
    app = SocketGameApplication(server_config, server_class)
    app.start()
Ejemplo n.º 7
0
class TestServerSystem(TestCase):
    condition = Condition()

    CLIENT_COUNT = 3
    server_class = ThreadedTCPServer
    client_class = BlockingTCPClient

    server_config = HouseConfig(house_id="0", data_dir_path="initial_configs/", protocol_class=MyGameProtocol)
    client_config = GameClientConfig("localhost", 41001, MyGameClientProtocol)

    server_app = None
    server_app_thread = None
    clients = []
    client_thread_by_client = {}

    @staticmethod
    def make_auth_sig(social_id, access_token, app_secret):
        md5 = hashlib.md5()
        md5.update((social_id + "_" + access_token + "_" + app_secret).encode('utf-8'))
        sig = md5.hexdigest()
        return sig

    def setUp(self):
        super().setUp()

        self.server_app = SocketGameApplication(self.server_config, self.server_class)
        self.start_server(self.server_app)

        for i in range(self.CLIENT_COUNT):
            credentials = {
                "user_id": str(i + 1),
                "social_id": str(i + 1001),
                "access_token": "qwertyuiopasdfghjklzxcvbnm" + str(i + 1),
                "auth_sig": TestServerSystem.make_auth_sig(str(i + 1), 
                                                           "qwertyuiopasdfghjklzxcvbnm" + str(i + 1), 
                                                           "tyuiop12345"),
                "backend": "fb_local"
            }
            client = self.client_class(self.client_config, credentials)
            self.clients.append(client)
            self.clients.append(client)

    def tearDown(self):
        super().tearDown()

        self.server_app.dispose()
        self.server_app_thread.join()
        # (list() needed to make a copy)
        for client in list(self.clients):
            client.dispose()
        for client, client_thread in self.client_thread_by_client:
            client_thread.join()
        self.server_app = None
        self.server_app_thread = None
        self.clients.clear()
        self.client_thread_by_client.clear()

    # Utility

    def start_server(self):
        self.server_app_thread = Thread(target=self.server_app.start)
        self.server_app_thread.start()

    def stop_server(self):
        self.server_app.stop()
        self.server_app_thread.join()

    def connect_client(self, client):
        client_thread = Thread(target=client.connect)
        client_thread.start()
        self.client_thread_by_client[client] = client_thread

    def close_client(self, client):
        client.close()
        client_thread = self.client_thread_by_client[client]
        client_thread.join()

    # Tests

    def test_client_server_connections(self):
        house = self.server_app.house
        # client1 and client2 are of same user
        client1 = self.clients[0]
        client2 = self.clients[1]
        client3 = self.clients[2]

        # Ensure house created successfully
        self.assertEqual(len(house.house_model.lobby_model_list), 3)

        # Test 3 client of 2 users connected
        self.connect_client(client1)
        self.connect_client(client2)
        self.connect_client(client3)

        with self.condition:
            self.condition.wait_for(lambda : len(client1.protocol.processed_command_codes) > 1)
        # client1.protocol.processed_command_codes.clear()

        self.assertEqual(len(house.users_online), 2)
        self.assertEqual(len(house.players_online), 3)
        self.assertEqual(len(house.players_connected), 3)

        # Disconnect 1st client
        self.close_client(client1)

        self.assertEqual(len(house.users_online), 2)
        self.assertEqual(len(house.players_online), 2)
        self.assertEqual(len(house.players_connected), 2)

        # Disconnect 3rd client
        self.close_client(client1)

        self.assertEqual(len(house.users_online), 1)
        self.assertEqual(len(house.players_online), 1)
        self.assertEqual(len(house.players_connected), 1)

        # Restart server (test save/restore)
        self.stop_server()
        self.start_server()
        house = self.server_app.house

        self.assertEqual(len(house.users_online), 12)
        self.assertEqual(len(house.players_online), 1)
        self.assertEqual(len(house.players_connected), 1)

        # Reconnect 1st client
        self.connect_client(client1)

        self.assertEqual(len(house.users_online), 2)
        self.assertEqual(len(house.players_online), 2)
        self.assertEqual(len(house.players_connected), 2)
Ejemplo n.º 8
0
class TestNonBlockingTCPServer(TestAbstractServer):
    address = ("localhost", 12345)
    config = ServerConfig(*address, Protocol)
    app = SocketGameApplication(config)

    def setUp(self):
        # super().setUp()

        # # For test_start_stop()
        # patcher = patch("napalm.socket.server.NonBlockingTCPServer", MyNonBlockingTCPServer)
        # self.addCleanup(patcher.stop)
        # patcher.start()

        self.server = MyNonBlockingTCPServer(self.config, self.app)

    def test_init_default(self):
        with self.assertRaises(Exception):
            NonBlockingTCPServer(None)

    @patch("socket.socket")
    def test_start(self, sock_mock=None):
        # Skipping workflow loop
        self.server._workflow = Mock()
        # Simulate workflow activity
        protocol = MagicMock()
        self.server._request_by_protocol = {protocol: Mock()}
        self.server._buffer_by_protocol = {protocol: b"data"}
        self.server._protocol_list = [protocol]

        self.server.start()
        # Should skip others without errors
        self.server.start()
        self.server.start()

        self.assertEqual(sock_mock.mock_calls[0],
                         call(socket.AF_INET, socket.SOCK_STREAM))
        self.assertEqual(
            sock_mock.mock_calls[1],
            call().setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1))
        self.assertEqual(sock_mock.mock_calls[2], call().bind(self.address))
        self.assertEqual(sock_mock.mock_calls[3], call().listen())
        self.assertEqual(sock_mock.mock_calls[4], call().setblocking(0))
        self.assertEqual(sock_mock.mock_calls[5],
                         call().shutdown(socket.SHUT_RDWR))
        self.assertEqual(sock_mock.mock_calls[6], call().close())
        # Should be cleared after serving ended
        self.assertIsNone(self.server._sock)
        protocol.dispose.assert_called_once()
        self.assertEqual(self.server._protocol_list, [])
        self.assertEqual(self.server._request_by_protocol, {})
        self.assertEqual(self.server._buffer_by_protocol, {})

    def test_stop(self):
        self.assertFalse(self.server._abort)

        self.server.started = True

        self.server.stop()
        # Should skip others without errors
        self.server.stop()
        self.server.stop()

        self.assertTrue(self.server._abort)

    def test_start_stop(self):
        MyNonBlockingTCPServer.started_event.clear()

        # Start server
        thread = Thread(target=self.server.start)
        thread.start()
        # Should skip others without errors
        self.server.start()
        self.server.start()

        # Wait until server started (workflow began)
        MyNonBlockingTCPServer.started_event.wait()

        self.assertFalse(self.server._abort)
        self.assertIsNotNone(self.server._sock)
        self.assertEqual(self.server._sock.getsockname(),
                         ("127.0.0.1", self.address[1]))

        sock = self.server._sock

        self.server.stop()
        # Should skip others without errors
        self.server.stop()
        self.server.stop()

        # Should be cleared after serving ended
        self.assertTrue(self.server._abort)
        self.assertIsNone(self.server._sock)
        with self.assertRaises(OSError):
            # Error means socket closed
            # (OSError: [WinError 10038] Сделана попытка выполнить операцию на объекте, не являющемся сокетом)
            self.assertIsNone(sock.getsockname())
        # Check non-blocking (None - for blocking)
        self.assertEqual(sock.timeout, 0)

        thread.join()

    def test_workflow(self):
        requests = [MagicMock(), MagicMock(), MagicMock()]
        protocols = [MyProtocol(), MyProtocol(), MyProtocol(), MyProtocol()]

        # Set up data received by request and processed by protocol
        # (Connection lost on recv() returns empty)
        requests[0].recv = Mock(side_effect=[
            b"1||param1||", MyWouldBlockSocketError,
            b"param2##\x002||param1||param2##\x00", MyWouldBlockSocketError,
            b"3||", b"param1||", b"param2##\x00", MyWouldBlockSocketError,
            b"4||param1||param2##\x00", b"", b"5||param1||param2##\x00"
        ])
        protocols[0].process_bytes_list = Mock()

        # (Connection lost on recv() raises socket.error)
        requests[1].recv = Mock(side_effect=[
            b"6||",
            b"param1||",
            b"param2##\x00",
            MyWouldBlockSocketError,
            b"7||param1||param2##\x00",
            # (In our server implementation we suggest that error could not occur before
            # between blocking if we've already received some data.
            # So we place MyWouldBlockSocketError before socket.error.)
            MyWouldBlockSocketError,
            socket.error,
            b"8||param1||param2##\x00"
        ])
        # protocols[1].process_bytes_list = Mock(
        #     side_effect={b"4||param1||param2##": socket.error})
        protocols[1].process_bytes_list = Mock()

        # (Connection lost on protocol.process_bytes_list() raises exception)
        requests[2].recv = Mock(side_effect=[
            b"9||", b"param1||", b"param2##\x00", MyWouldBlockSocketError,
            b"10||param1||param2##\x00", MyWouldBlockSocketError,
            b"11||param1||param2##\x00"
        ])

        def do_raise(data_bytes_list):
            if data_bytes_list == [b"10||param1||param2##"]:
                raise MySpecificException

        protocols[2].process_bytes_list = Mock(side_effect=do_raise)

        # Expected results
        expected_call_args_list = [
            [
                call([b"1||param1||param2##", b"2||param1||param2##"]),
                call([b"3||param1||param2##"]),
                call([b"4||param1||param2##"])
            ],
            [call([b"6||param1||param2##"]),
             call([b"7||param1||param2##"])],
            [call([b"9||param1||param2##"]),
             call([b"10||param1||param2##"])],
            [
                # Current protocol is not used
            ]
        ]

        self.do_test_workflow(requests, protocols, expected_call_args_list)

        # todo assert instances in protocol_list and lookups

    def test_workflow_with_abort(self):
        requests = [MagicMock(), MagicMock()]
        protocols = [MyProtocol(), MyProtocol(), MyProtocol()]

        # Set up data received by request and processed by protocol
        # (Connection lost on recv() returns empty)
        requests[0].recv = Mock(side_effect=[
            b"1||param1||", MyWouldBlockSocketError,
            b"param2##\x002||param1||param2##\x00", MyWouldBlockSocketError,
            b"3||", b"param1||", b"param2##\x00", MyWouldBlockSocketError,
            b"4||param1||param2##\x00", b"", b"5||param1||param2##\x00"
        ])

        protocols[0].process_bytes_list = Mock()

        # (Connection lost on recv() raises socket.error)
        requests[1].recv = Mock(side_effect=[
            b"6||", b"param1||", b"param2##\x00", MyWouldBlockSocketError,
            b"7||param1||param2##\x00", MyWouldBlockSocketError,
            b"8||param1||param2##\x00"
        ])

        def do_abort(data_bytes_list):
            if data_bytes_list == [b"7||param1||param2##"]:
                self.server._abort = True

        protocols[1].process_bytes_list = Mock(side_effect=do_abort)

        # Expected results
        expected_call_args_list = [
            [
                call([b"1||param1||param2##", b"2||param1||param2##"]),
                call([b"3||param1||param2##"]),
                # call([b"4||param1||param2##"])
            ],
            [
                call([b"6||param1||param2##"]),
                call([b"7||param1||param2##"])
                # Aborted
            ],
            [
                # Current protocol is not used
            ]
        ]

        self.do_test_workflow(requests, protocols, expected_call_args_list)

        # todo assert instances in protocol_list and lookups

    def do_test_workflow(self, requests, protocols, expected_call_args_list):
        # (All process_bytes_list methods should be mocked)
        for protocol in protocols:
            if not isinstance(protocol.process_bytes_list, Mock):
                protocol.process_bytes_list = Mock()

        # Set up connections
        # (Accepting connection and creating protocol for each)
        sock = MagicMock()
        accept_list = list([(request, ("somehost", random.randint(1000,
                                                                  60000)))
                            for request in requests])
        accept_list.append(socket.error)
        accept_list.insert(0, socket.error)
        sock.accept.side_effect = accept_list
        self.server.protocol_factory.create = Mock(side_effect=protocols)

        # Start
        MyProtocol.disposed_count = 0
        thread = Thread(target=self.server._workflow, args=[sock])
        thread.start()

        # Wait until all protocol disposed to abort workflow
        # (Note: we take len(requests), because len(protocols) could be > len(requests))
        while MyProtocol.disposed_count < len(
                requests) and not self.server._abort:
            pass
        self.server._abort = True
        # thread.join()

        # Assert
        for index, expected_call_args in enumerate(expected_call_args_list):
            actual_call_args = protocols[
                index].process_bytes_list.call_args_list
            self.assertEqual(actual_call_args, expected_call_args)
Ejemplo n.º 9
0
class TestThreadedTCPServer(TestAbstractServer):
    address = ("localhost", 12345)
    config = ServerConfig(*address, Protocol)
    app = SocketGameApplication(config)

    def setUp(self):
        # super().setUp()

        # For test_start_stop()
        patcher = patch("socketserver.ThreadingTCPServer",
                        MyThreadingTCPServer)
        self.addCleanup(patcher.stop)
        patcher.start()

        self.server = ThreadedTCPServer(self.config, self.app)

    def test_init_default(self):
        with self.assertRaises(Exception):
            ThreadedTCPServer(None)

    @patch("socketserver.ThreadingTCPServer")
    def test_start(self, server_mock=None):
        self.server.start()
        # Should skip others without errors
        self.server.start()
        self.server.start()

        self.assertEqual(server_mock.mock_calls[0],
                         call(self.address, ThreadedTCPHandler))
        self.assertEqual(server_mock.mock_calls[1], call().serve_forever())
        self.assertEqual(server_mock.mock_calls[2], call().server_close())
        # Should be cleared after serving ended
        self.assertTrue(server_mock.return_value.abort)
        self.assertIsNone(server_mock.return_value.protocol_factory)
        self.assertIsNone(server_mock.return_value.config)
        self.assertIsNone(self.server.server)

    def test_stop(self):
        # No exception
        self.assertIsNone(self.server.server)

        self.server.stop()

        # Check shutdown() called
        self.server.server = MagicMock()
        self.server.started = True

        self.server.stop()
        # Should skip others without errors
        self.server.stop()
        self.server.stop()

        self.server.server.shutdown.assert_called_once()

    def test_start_stop(self):
        MyThreadingTCPServer.started_event.clear()

        # Start server
        thread = Thread(target=self.server.start)
        thread.start()
        # Should skip others without errors
        self.server.start()
        self.server.start()

        MyThreadingTCPServer.started_event.wait()

        self.assertIsNotNone(self.server.server)
        self.assertFalse(self.server.server.abort)
        self.assertEqual(self.server.server.protocol_factory,
                         self.server.protocol_factory)
        self.assertEqual(self.server.server.config, self.config)

        threading_server = self.server.server

        self.server.stop()
        # Should skip others without errors
        self.server.stop()
        self.server.stop()

        # Should be cleared after serving ended
        self.assertTrue(threading_server.abort)
        self.assertIsNone(threading_server.protocol_factory)
        self.assertIsNone(threading_server.config)
        self.assertIsNone(self.server.server)

        thread.join()
Ejemplo n.º 10
0
class TestThreadedTCPHandler(TestCase):
    address = ("somehost", 12345)
    config = ServerConfig(*address, Protocol)
    app = SocketGameApplication(config)
    protocol_factory = ProtocolFactory(config, app)

    def setUp(self):
        super().setUp()

        self.request = Mock()
        self.request.close = Mock()
        self.server = Mock(protocol_factory=self.protocol_factory,
                           config=self.config,
                           abort=False)

        # temp
        self.server.abort = True
        assert self.server.abort
        self.server.abort = False

        self.handler = MyThreadedTCPHandler(self.request, self.address,
                                            self.server)
        self.handler.setup()

    def test_setup(self):
        self.handler = MyThreadedTCPHandler(self.request, self.address,
                                            self.server)

        self.assertIsNone(self.handler.protocol)

        self.handler.setup()

        self.assertIsNotNone(self.handler.protocol)
        self.assertIsInstance(self.handler.protocol, Protocol)
        self.assertEqual(self.handler.protocol.send_bytes_method,
                         self.handler.send_bytes)
        self.assertEqual(self.handler.protocol.close_connection_method,
                         self.request.close)
        self.assertEqual(self.handler.protocol.address, self.address)

    def test_finish(self):
        self.handler.protocol.dispose = dispose_protocol = Mock()

        self.handler.finish()

        dispose_protocol.assert_called_once()
        self.assertIsNone(self.handler.protocol)

    def test_send_bytes(self):
        self.request.sendall = Mock()

        self.handler.send_bytes(b"some_bytes")

        self.request.sendall.assert_called_once_with(b"some_bytes\x00")

    def test_handle(self):
        # Connection lost on recv() returns empty
        self.request.recv = Mock(side_effect=[
            b"1||param1||", b"param2##\x002||param1||param2##\x00", b"3||",
            b"param1||", b"param2##\x00", b"4||param1||param2##\x00", b"",
            b"5||param1||param2##\x00"
        ])
        self.handler.protocol.process_bytes_list = process_bytes_list_mock = Mock(
        )

        self.handler.handle()

        self.assertEqual(process_bytes_list_mock.call_args_list, [
            call([b"1||param1||param2##", b"2||param1||param2##"]),
            call([b"3||param1||param2##"]),
            call([b"4||param1||param2##"])
        ])

    def test_handle__abort(self):
        # Stop on abort (on b"4||..." message)
        process_bytes_list_mock = Mock()

        def do_abort(data_bytes_list):
            process_bytes_list_mock(data_bytes_list)
            if data_bytes_list == [b"4||param1||param2##"]:
                self.server.abort = True

        self.request.recv = Mock(side_effect=[
            b"3||", b"param1||", b"param2##\x00", b"4||param1||param2##\x00",
            b"5||param1||param2##\x00"
        ])
        self.handler.protocol.process_bytes_list = do_abort

        self.handler.handle()

        self.assertEqual(
            process_bytes_list_mock.call_args_list,
            [call([b"3||param1||param2##"]),
             call([b"4||param1||param2##"])])

    def test_handle__recv_raises_exception(self):
        # Connection lost on recv() raises socket.error
        self.request.recv = Mock(side_effect=[
            b"3||", b"param1||", b"param2##\x00", b"4||param1||param2##\x00",
            socket.error, b"5||param1||param2##\x00"
        ])
        self.handler.protocol.process_bytes_list = process_bytes_list_mock = Mock(
            side_effect={b"4||param1||param2##": socket.error})

        self.handler.handle()

        self.assertEqual(
            process_bytes_list_mock.call_args_list,
            [call([b"3||param1||param2##"]),
             call([b"4||param1||param2##"])])

    def test_handle__process_raises_exception(self):
        # Connection lost on protocol.process_bytes_list() raises exception
        self.request.recv = Mock(side_effect=[
            b"3||", b"param1||", b"param2##\x00", b"4||param1||param2##\x00",
            b"5||param1||param2##\x00"
        ])

        def do_raise(data_bytes_list):
            if data_bytes_list == [b"4||param1||param2##"]:
                raise MySpecificException

        self.handler.protocol.process_bytes_list = Mock(side_effect=do_raise)

        self.handler.handle()

        self.assertEqual(
            self.handler.protocol.process_bytes_list.call_args_list,
            [call([b"3||param1||param2##"]),
             call([b"4||param1||param2##"])])