Ejemplo n.º 1
0
    def test_init_and_reg_shutdown(self):
        """
        Test initialization of a socket manager.
        """
        self.assertFalse(self.fake_socket.connected)

        # Callbacks should never trigger during proper setup and shutdown
        nop_called = False

        def nop(*args):
            nonlocal nop_called  # noqa 999 we don't support py2
            nop_called = True

        socket_manager = SocketManager(
            'https://127.0.0.1',
            self.fake_socket.port,
            nop,
            nop,
            nop,
            TASK_GROUP_ID_1,
            0.3,
            nop,
        )
        self.assertTrue(self.fake_socket.connected)
        self.assertFalse(nop_called)

        # Test shutdown
        self.assertFalse(self.fake_socket.disconnected)
        self.assertFalse(socket_manager.is_shutdown)
        self.assertTrue(socket_manager.alive)
        socket_manager.shutdown()
        time.sleep(0.3)
        self.assertTrue(self.fake_socket.disconnected)
        self.assertTrue(socket_manager.is_shutdown)
        self.assertFalse(nop_called)
    def setUp(self):
        self.fake_socket = MockSocket()
        time.sleep(0.3)
        self.agent1 = MockAgent(
            TEST_HIT_ID_1, TEST_ASSIGNMENT_ID_1, TEST_WORKER_ID_1, TASK_GROUP_ID_1
        )
        self.agent2 = MockAgent(
            TEST_HIT_ID_2, TEST_ASSIGNMENT_ID_2, TEST_WORKER_ID_2, TASK_GROUP_ID_1
        )
        self.alive_packet = None
        self.message_packet = None
        self.dead_worker_id = None
        self.dead_assignment_id = None
        self.server_died = False

        self.socket_manager = SocketManager(
            'https://127.0.0.1',
            3030,
            self.on_alive,
            self.on_message,
            self.on_worker_death,
            TASK_GROUP_ID_1,
            1,
            self.on_server_death,
        )
Ejemplo n.º 3
0
    def setUp(self):
        self.AGENT_ALIVE_PACKET = Packet(
            MESSAGE_ID_1,
            data_model.AGENT_ALIVE,
            self.SENDER_ID,
            self.WORLD_ID,
            self.ASSIGNMENT_ID,
            self.DATA,
            self.CONVERSATION_ID,
        )

        self.MESSAGE_SEND_PACKET_1 = Packet(
            MESSAGE_ID_2,
            data_model.WORLD_MESSAGE,
            self.WORLD_ID,
            self.SENDER_ID,
            self.ASSIGNMENT_ID,
            self.DATA,
            self.CONVERSATION_ID,
        )

        self.MESSAGE_SEND_PACKET_2 = Packet(
            MESSAGE_ID_3,
            data_model.MESSAGE_BATCH,
            self.WORLD_ID,
            self.SENDER_ID,
            self.ASSIGNMENT_ID,
            self.DATA,
            self.CONVERSATION_ID,
        )

        self.MESSAGE_SEND_PACKET_3 = Packet(
            MESSAGE_ID_4,
            data_model.MESSAGE_BATCH,
            self.WORLD_ID,
            self.SENDER_ID,
            self.ASSIGNMENT_ID,
            self.DATA,
            self.CONVERSATION_ID,
        )

        self.fake_socket = MockSocket()
        time.sleep(0.3)
        self.alive_packet = None
        self.message_packet = None
        self.dead_worker_id = None
        self.dead_assignment_id = None
        self.server_died = False

        self.socket_manager = SocketManager(
            'https://127.0.0.1',
            self.fake_socket.port,
            self.on_alive,
            self.on_message,
            self.on_worker_death,
            TASK_GROUP_ID_1,
            1,
            self.on_server_death,
        )
Ejemplo n.º 4
0
    def test_init_world_dead(self):
        """
        Test initialization of a socket manager with a failed startup.
        """
        self.assertFalse(self.fake_socket.connected)
        self.fake_socket.close()

        # Callbacks should never trigger during proper setup and shutdown
        nop_called = False

        def nop(*args):
            nonlocal nop_called  # noqa 999 we don't support py2
            nop_called = True

        server_death_called = False

        def server_death(*args):
            nonlocal server_death_called
            server_death_called = True

        with self.assertRaises(ConnectionRefusedError):
            socket_manager = SocketManager(
                'https://127.0.0.1',
                self.fake_socket.port,
                nop,
                nop,
                nop,
                TASK_GROUP_ID_1,
                0.4,
                server_death,
            )
            self.assertIsNone(socket_manager)

        self.assertFalse(nop_called)
        self.assertTrue(server_death_called)
Ejemplo n.º 5
0
    def test_init_and_socket_shutdown_then_restart(self):
        """
        Test restoring connection to a socket.
        """
        self.assertFalse(self.fake_socket.connected)

        # Callbacks should never trigger during proper setup and shutdown
        nop_called = False

        def nop(*args):
            nonlocal nop_called  # noqa 999 we don't support py2
            nop_called = True

        server_death_called = False

        def server_death(*args):
            nonlocal server_death_called
            server_death_called = True

        socket_manager = SocketManager(
            'https://127.0.0.1',
            self.fake_socket.port,
            nop,
            nop,
            nop,
            TASK_GROUP_ID_1,
            0.4,
            server_death,
        )
        self.assertTrue(self.fake_socket.connected)
        self.assertFalse(nop_called)
        self.assertFalse(server_death_called)

        # Test shutdown
        self.assertFalse(self.fake_socket.disconnected)
        self.assertFalse(socket_manager.is_shutdown)
        self.assertTrue(socket_manager.alive)
        self.fake_socket.close()
        self.assertEqualBy(lambda: socket_manager.alive, False, 8)
        self.assertFalse(socket_manager.alive)
        self.fake_socket = MockSocket()
        self.assertEqualBy(lambda: socket_manager.alive, True, 4)
        self.assertFalse(nop_called)
        self.assertFalse(server_death_called)
        socket_manager.shutdown()
Ejemplo n.º 6
0
    def test_init_and_socket_shutdown(self):
        '''Test initialization of a socket manager with a failed shutdown'''
        self.assertFalse(self.fake_socket.connected)

        # Callbacks should never trigger during proper setup and shutdown
        nop_called = False

        def nop(*args):
            nonlocal nop_called  # noqa 999 we don't support py2
            nop_called = True

        server_death_called = False

        def server_death(*args):
            nonlocal server_death_called
            server_death_called = True

        socket_manager = SocketManager(
            'https://127.0.0.1',
            self.fake_socket.port,
            nop,
            nop,
            nop,
            TASK_GROUP_ID_1,
            0.4,
            server_death,
        )
        self.assertTrue(self.fake_socket.connected)
        self.assertFalse(nop_called)
        self.assertFalse(server_death_called)

        # Test shutdown
        self.assertFalse(self.fake_socket.disconnected)
        self.assertFalse(socket_manager.is_shutdown)
        self.assertTrue(socket_manager.alive)
        self.fake_socket.close()
        self.assertEqualBy(lambda: socket_manager.alive, False, 8)
        self.assertEqualBy(lambda: server_death_called, True, 20)
        self.assertFalse(nop_called)
        socket_manager.shutdown()
Ejemplo n.º 7
0
class TestSocketManagerMessageHandling(unittest.TestCase):
    """
    Test sending messages to the world and then to each of two agents, along with
    failure cases for each.
    """
    def on_alive(self, packet):
        self.alive_packet = packet
        self.socket_manager.open_channel(packet.sender_id,
                                         packet.assignment_id)

    def on_message(self, packet):
        self.message_packet = packet

    def on_worker_death(self, worker_id, assignment_id):
        self.dead_worker_id = worker_id
        self.dead_assignment_id = assignment_id

    def on_server_death(self):
        self.server_died = True

    def assertEqualBy(self, val_func, val, max_time):
        start_time = time.time()
        while val_func() != val:
            assert (time.time() - start_time <
                    max_time), "Value was not attained in specified time"
            time.sleep(0.1)

    def setUp(self):
        self.fake_socket = MockSocket()
        time.sleep(0.3)
        self.agent1 = MockAgent(TEST_HIT_ID_1, TEST_ASSIGNMENT_ID_1,
                                TEST_WORKER_ID_1, TASK_GROUP_ID_1)
        self.agent2 = MockAgent(TEST_HIT_ID_2, TEST_ASSIGNMENT_ID_2,
                                TEST_WORKER_ID_2, TASK_GROUP_ID_1)
        self.alive_packet = None
        self.message_packet = None
        self.dead_worker_id = None
        self.dead_assignment_id = None
        self.server_died = False

        self.socket_manager = SocketManager(
            'https://127.0.0.1',
            3030,
            self.on_alive,
            self.on_message,
            self.on_worker_death,
            TASK_GROUP_ID_1,
            1,
            self.on_server_death,
        )

    def tearDown(self):
        self.socket_manager.shutdown()
        self.fake_socket.close()

    def test_alive_send_and_disconnect(self):
        message_packet = None

        def on_msg(*args):
            nonlocal message_packet
            message_packet = args[0]

        self.agent1.register_to_socket(self.fake_socket, on_msg)
        self.assertIsNone(message_packet)

        # Assert alive is registered
        alive_id = self.agent1.send_alive()
        self.assertIsNone(message_packet)
        self.assertIsNone(self.message_packet)
        self.assertEqualBy(lambda: self.alive_packet is None, False, 8)
        self.assertEqual(self.alive_packet.id, alive_id)

        # Test message send from agent
        test_message_text_1 = 'test_message_text_1'
        msg_id = self.agent1.send_message(test_message_text_1)
        self.assertEqualBy(lambda: self.message_packet is None, False, 8)
        self.assertEqual(self.message_packet.id, msg_id)
        self.assertEqual(self.message_packet.data['text'], test_message_text_1)

        # Test message send to agent
        manager_message_id = 'message_id_from_manager'
        test_message_text_2 = 'test_message_text_2'
        message_send_packet = Packet(
            manager_message_id,
            data_model.MESSAGE_BATCH,
            self.socket_manager.get_my_sender_id(),
            TEST_WORKER_ID_1,
            TEST_ASSIGNMENT_ID_1,
            test_message_text_2,
            't2',
        )
        self.socket_manager.queue_packet(message_send_packet)
        self.assertEqualBy(lambda: message_packet is None, False, 8)
        self.assertEqual(message_packet.id, manager_message_id)
        self.assertEqual(message_packet.data, test_message_text_2)
        self.assertIn(manager_message_id, self.socket_manager.packet_map)

        # Test agent disconnect
        self.agent1.send_disconnect()
        self.assertEqualBy(lambda: self.dead_worker_id, TEST_WORKER_ID_1, 8)
        self.assertEqual(self.dead_assignment_id, TEST_ASSIGNMENT_ID_1)

    def test_one_agent_disconnect_other_alive(self):
        message_packet = None

        def on_msg(*args):
            nonlocal message_packet
            message_packet = args[0]

        self.agent1.register_to_socket(self.fake_socket, on_msg)
        self.agent2.register_to_socket(self.fake_socket, on_msg)
        self.assertIsNone(message_packet)

        # Assert alive is registered
        self.agent1.send_alive()
        self.agent2.send_alive()
        self.assertIsNone(message_packet)

        # Kill second agent
        self.agent2.send_disconnect()
        self.assertEqualBy(lambda: self.dead_worker_id, TEST_WORKER_ID_2, 8)
        self.assertEqual(self.dead_assignment_id, TEST_ASSIGNMENT_ID_2)

        # Run rest of tests

        # Test message send from agent
        test_message_text_1 = 'test_message_text_1'
        msg_id = self.agent1.send_message(test_message_text_1)
        self.assertEqualBy(lambda: self.message_packet is None, False, 8)
        self.assertEqual(self.message_packet.id, msg_id)
        self.assertEqual(self.message_packet.data['text'], test_message_text_1)

        # Test message send to agent
        manager_message_id = 'message_id_from_manager'
        test_message_text_2 = 'test_message_text_2'
        message_send_packet = Packet(
            manager_message_id,
            data_model.WORLD_MESSAGE,
            self.socket_manager.get_my_sender_id(),
            TEST_WORKER_ID_1,
            TEST_ASSIGNMENT_ID_1,
            test_message_text_2,
            't2',
        )
        self.socket_manager.queue_packet(message_send_packet)
        self.assertEqualBy(lambda: message_packet is None, False, 8)
        self.assertEqual(message_packet.id, manager_message_id)
        self.assertEqual(message_packet.data, test_message_text_2)
        self.assertIn(manager_message_id, self.socket_manager.packet_map)

        # Test agent disconnect
        self.agent1.send_disconnect()
        self.assertEqualBy(lambda: self.dead_worker_id, TEST_WORKER_ID_1, 8)
        self.assertEqual(self.dead_assignment_id, TEST_ASSIGNMENT_ID_1)
Ejemplo n.º 8
0
class TestSocketManagerRoutingFunctionality(unittest.TestCase):

    ID = 'ID'
    SENDER_ID = 'SENDER_ID'
    ASSIGNMENT_ID = 'ASSIGNMENT_ID'
    DATA = 'DATA'
    CONVERSATION_ID = 'CONVERSATION_ID'
    ACK_FUNCTION = 'ACK_FUNCTION'
    WORLD_ID = '[World_{}]'.format(TASK_GROUP_ID_1)

    def on_alive(self, packet):
        self.alive_packet = packet

    def on_message(self, packet):
        self.message_packet = packet

    def on_worker_death(self, worker_id, assignment_id):
        self.dead_worker_id = worker_id
        self.dead_assignment_id = assignment_id

    def on_server_death(self):
        self.server_died = True

    def setUp(self):
        self.AGENT_ALIVE_PACKET = Packet(
            MESSAGE_ID_1,
            data_model.AGENT_ALIVE,
            self.SENDER_ID,
            self.WORLD_ID,
            self.ASSIGNMENT_ID,
            self.DATA,
            self.CONVERSATION_ID,
        )

        self.MESSAGE_SEND_PACKET_1 = Packet(
            MESSAGE_ID_2,
            data_model.WORLD_MESSAGE,
            self.WORLD_ID,
            self.SENDER_ID,
            self.ASSIGNMENT_ID,
            self.DATA,
            self.CONVERSATION_ID,
        )

        self.MESSAGE_SEND_PACKET_2 = Packet(
            MESSAGE_ID_3,
            data_model.MESSAGE_BATCH,
            self.WORLD_ID,
            self.SENDER_ID,
            self.ASSIGNMENT_ID,
            self.DATA,
            self.CONVERSATION_ID,
        )

        self.MESSAGE_SEND_PACKET_3 = Packet(
            MESSAGE_ID_4,
            data_model.MESSAGE_BATCH,
            self.WORLD_ID,
            self.SENDER_ID,
            self.ASSIGNMENT_ID,
            self.DATA,
            self.CONVERSATION_ID,
        )

        self.fake_socket = MockSocket()
        time.sleep(0.3)
        self.alive_packet = None
        self.message_packet = None
        self.dead_worker_id = None
        self.dead_assignment_id = None
        self.server_died = False

        self.socket_manager = SocketManager(
            'https://127.0.0.1',
            self.fake_socket.port,
            self.on_alive,
            self.on_message,
            self.on_worker_death,
            TASK_GROUP_ID_1,
            1,
            self.on_server_death,
        )

    def tearDown(self):
        self.socket_manager.shutdown()
        self.fake_socket.close()

    def test_init_state(self):
        """
        Ensure all of the initial state of the socket_manager is ready.
        """
        self.assertEqual(self.socket_manager.server_url, 'https://127.0.0.1')
        self.assertEqual(self.socket_manager.port, self.fake_socket.port)
        self.assertEqual(self.socket_manager.alive_callback, self.on_alive)
        self.assertEqual(self.socket_manager.message_callback, self.on_message)
        self.assertEqual(self.socket_manager.socket_dead_callback,
                         self.on_worker_death)
        self.assertEqual(self.socket_manager.task_group_id, TASK_GROUP_ID_1)
        self.assertEqual(self.socket_manager.missed_pongs,
                         1 + (1 / SocketManager.PING_RATE))
        self.assertIsNotNone(self.socket_manager.ws)
        self.assertTrue(self.socket_manager.keep_running)
        self.assertIsNotNone(self.socket_manager.listen_thread)
        self.assertSetEqual(self.socket_manager.open_channels, set())
        self.assertDictEqual(self.socket_manager.packet_map, {})
        self.assertTrue(self.socket_manager.alive)
        self.assertFalse(self.socket_manager.is_shutdown)
        self.assertEqual(self.socket_manager.get_my_sender_id(), self.WORLD_ID)

    def _send_packet_in_background(self, packet, send_time):
        """
        creates a thread to handle waiting for a packet send.
        """
        def do_send():
            self.socket_manager._send_packet(packet, send_time)
            self.sent = True

        send_thread = threading.Thread(target=do_send, daemon=True)
        send_thread.start()
        time.sleep(0.02)

    def test_packet_send(self):
        """
        Checks to see if packets are working.
        """
        self.socket_manager._safe_send = mock.MagicMock()
        self.sent = False

        # Test a blocking acknowledged packet
        send_time = time.time()
        self.assertEqual(self.MESSAGE_SEND_PACKET_2.status, Packet.STATUS_INIT)
        self._send_packet_in_background(self.MESSAGE_SEND_PACKET_2, send_time)
        self.assertEqual(self.MESSAGE_SEND_PACKET_2.status, Packet.STATUS_SENT)
        self.socket_manager._safe_send.assert_called_once()
        self.assertTrue(self.sent)

        used_packet_json = self.socket_manager._safe_send.call_args[0][0]
        used_packet_dict = json.loads(used_packet_json)
        self.assertEqual(used_packet_dict['type'], data_model.MESSAGE_BATCH)
        self.assertDictEqual(used_packet_dict['content'],
                             self.MESSAGE_SEND_PACKET_2.as_dict())

    def test_simple_packet_channel_management(self):
        """
        Ensure that channels are created, managed, and then removed as expected.
        """
        use_packet = self.MESSAGE_SEND_PACKET_1
        worker_id = use_packet.receiver_id
        assignment_id = use_packet.assignment_id

        # Open a channel and assert it is there
        self.socket_manager.open_channel(worker_id, assignment_id)
        time.sleep(0.1)
        connection_id = use_packet.get_receiver_connection_id()

        self.assertIn(connection_id, self.socket_manager.open_channels)
        self.assertTrue(self.socket_manager.socket_is_open(connection_id))
        self.assertFalse(self.socket_manager.socket_is_open(FAKE_ID))

        # Send a packet to an open socket, ensure it got queued
        resp = self.socket_manager.queue_packet(use_packet)
        self.assertIn(use_packet.id, self.socket_manager.packet_map)
        self.assertTrue(resp)

        # Assert we can get the status of a packet in the map, but not
        # existing doesn't throw an error
        self.assertEqual(self.socket_manager.get_status(use_packet.id),
                         use_packet.status)
        self.assertEqual(self.socket_manager.get_status(FAKE_ID),
                         Packet.STATUS_NONE)

        # Assert that closing a thread does the correct cleanup work
        self.socket_manager.close_channel(connection_id)
        time.sleep(0.2)
        self.assertNotIn(connection_id, self.socket_manager.open_channels)
        self.assertNotIn(use_packet.id, self.socket_manager.packet_map)

        # Assert that opening multiple and closing them is possible
        self.socket_manager.open_channel(worker_id, assignment_id)
        self.socket_manager.open_channel(worker_id + '2', assignment_id)
        time.sleep(0.1)
        self.assertEqual(len(self.socket_manager.open_channels), 2)
        self.socket_manager.close_all_channels()
        time.sleep(0.1)
        self.assertEqual(len(self.socket_manager.open_channels), 0)