示例#1
0
    def test_receive_messages_success(self):
        # Tests that a remote proxy player can successfully receive a message from a client
        server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server_sock.bind(("localhost", self.port))
        server_sock.listen()

        # run client on separate thread
        def thread_func(port):
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.connect(("localhost", port))
            time.sleep(.1)
            sock.sendall(bytes('"void"', 'ascii'))
            if sock:
                sock.close()

        c_thread = threading.Thread(target=thread_func, args=(self.port, ))
        c_thread.start()

        client, address = server_sock.accept()
        rpp = RemotePlayerProxy('name', 1.0, client)

        response = rpp._RemotePlayerProxy__receive_messages()

        # close sockets
        if server_sock:
            server_sock.close()
        if rpp._RemotePlayerProxy__socket:
            rpp._RemotePlayerProxy__socket.close()

        self.assertEqual(response, ['void'])
示例#2
0
 def test_status_update(self):
     # Test that we simply return True for status_update
     rpp = RemotePlayerProxy('name', 1.0, self.dummy_socket)
     res = rpp.status_update(PlayerStatus.DISCONTINUED)
     self.assertEquals(res, True)
     res = rpp.status_update(PlayerStatus.WON_GAME)
     self.assertEquals(res, True)
示例#3
0
 def test_invalid_json_placement(self):
     # Tests that receiving invalid JSON results in a None placement
     rpp = RemotePlayerProxy('name', 1.0, self.dummy_socket)
     rpp._RemotePlayerProxy__socket = self.mock_socket
     self.mock_socket.recv.return_value = b'['
     state = State(self.__b, players=[self.__p1, self.__p2, self.__p3])
     pos = rpp.get_placement(state)
     self.assertEqual(pos, None)
示例#4
0
    def __init__(self, connection):
        """
		This class implements a remote player proxy contract which
		has the same interface as the player, but checks
		the sent and received messages for validity.
		"""
        self.name = None
        self.remote_player_proxy = RemotePlayerProxy(connection)
示例#5
0
    def test_valid_json_invalid_message(self):
        # Tests that valid JSON but invalid message returns JsonDecodeException
        rpp = RemotePlayerProxy('name', 1.0, self.dummy_socket)
        rpp._RemotePlayerProxy__socket = self.mock_socket
        self.mock_socket.recv.return_value = b'["test"]'

        with self.assertRaises(JsonDecodeException):
            state = State(self.__b, players=[self.__p1, self.__p2, self.__p3])
            pos = rpp.get_placement(state)
示例#6
0
    def test_tournament_start_success(self):
        # Test that RPP can successfully send a tournament start message and recieve ack
        rpp = RemotePlayerProxy('name', 1.0, self.dummy_socket)
        rpp._RemotePlayerProxy__socket = self.mock_socket
        self.mock_socket.recv.return_value = b'"void"'
        expected_client_request = f'["start", [true]]'

        with patch.object(rpp, '_RemotePlayerProxy__send_message') as mock:
            ack = rpp.tournament_has_started()
            mock.assert_called_with(expected_client_request)
            self.assertEqual(ack, True)
示例#7
0
    def test_playing_with_success(self):
        # Test that RPP can successfully send a color and receive ACK from client
        rpp = RemotePlayerProxy('name', 1.0, self.dummy_socket)
        rpp._RemotePlayerProxy__socket = self.mock_socket
        self.mock_socket.recv.return_value = b'"void"'
        expected_client_request = f'["playing-with", ["red", "brown"]]'

        with patch.object(rpp, '_RemotePlayerProxy__send_message') as mock:
            ack = rpp.notify_opponent_colors([Color.RED, Color.BROWN])
            mock.assert_called_with(expected_client_request)
            self.assertEqual(ack, True)
示例#8
0
    def test_set_color_no_ack(self):
        # Test that RPP will return False if no ack received for set_color
        rpp = RemotePlayerProxy('name', 1.0, self.dummy_socket)
        rpp._RemotePlayerProxy__socket = self.mock_socket
        self.mock_socket.recv.return_value = b'[1, 2]'
        expected_client_request = f'["playing-as", ["white"]]'

        with patch.object(rpp, '_RemotePlayerProxy__send_message') as mock:
            ack = rpp.set_color(Color.WHITE)
            mock.assert_called_with(expected_client_request)
            self.assertEqual(ack, False)
示例#9
0
    def test_tournament_start_no_ack(self):
        # Test that RPP will return False if no ack received for tournament_start
        rpp = RemotePlayerProxy('name', 1.0, self.dummy_socket)
        rpp._RemotePlayerProxy__socket = self.mock_socket
        self.mock_socket.recv.return_value = b'[][]'
        expected_client_request = f'["start", [true]]'

        with patch.object(rpp, '_RemotePlayerProxy__send_message') as mock:
            ack = rpp.tournament_has_started()
            mock.assert_called_with(expected_client_request)
            self.assertEqual(ack, False)
示例#10
0
    def test_playing_with_no_ack(self):
        # Test that RPP will return False if no ack received for set_color
        rpp = RemotePlayerProxy('name', 1.0, self.dummy_socket)
        rpp._RemotePlayerProxy__socket = self.mock_socket
        self.mock_socket.recv.return_value = b'whoops'
        expected_client_request = f'["playing-with", ["white", "black"]]'

        with patch.object(rpp, '_RemotePlayerProxy__send_message') as mock:
            ack = rpp.notify_opponent_colors([Color.WHITE, Color.BLACK])
            mock.assert_called_with(expected_client_request)
            self.assertEqual(ack, False)
示例#11
0
    def test_get_action_success(self):
        # Test that RPP can successfully request, receive, and decode an Action
        rpp = RemotePlayerProxy('name', 1.0, self.dummy_socket)
        rpp._RemotePlayerProxy__socket = self.mock_socket
        self.mock_socket.recv.return_value = b'[[0, 1], [2, 2]]'

        state = State(self.__b, players=[self.__p1, self.__p2, self.__p3])
        json_state = _state_to_json(state)

        expected_client_request = f'["take-turn", [{json.dumps(json_state)}, []]]'

        with patch.object(rpp, '_RemotePlayerProxy__send_message') as mock:
            action = rpp.get_action(state)
            mock.assert_called_with(expected_client_request)
            self.assertEqual(action, Action(Position(0, 1), Position(2, 2)))
示例#12
0
    def test_get_action_returns_position(self):
        # Test that receiving a position when asking for an action throws JsonDecodeException and returns None
        rpp = RemotePlayerProxy('name', 1.0, self.dummy_socket)
        rpp._RemotePlayerProxy__socket = self.mock_socket
        self.mock_socket.recv.return_value = b'[0, 1]'

        state = State(self.__b, players=[self.__p1, self.__p2, self.__p3])
        json_state = _state_to_json(state)

        expected_client_request = f'["take-turn", [{json.dumps(json_state)}, []]]'

        with patch.object(rpp, '_RemotePlayerProxy__send_message') as mock:
            with self.assertRaises(JsonDecodeException):
                action = rpp.get_action(state)
                mock.assert_called_with(expected_client_request)
                self.assertEqual(action, None)
示例#13
0
    def test_get_placement_success(self):
        # Test that RPP can successfully request, receive and decode a position
        # This is done to bypass the constructor type checking
        rpp = RemotePlayerProxy('name', 1.0, self.dummy_socket)
        rpp._RemotePlayerProxy__socket = self.mock_socket
        self.mock_socket.recv.return_value = b'[0, 1]'

        state = State(self.__b, players=[self.__p1, self.__p2, self.__p3])
        json_state = _state_to_json(state)

        expected_client_request = f'["setup", [{json.dumps(json_state)}]]'

        with patch.object(rpp, '_RemotePlayerProxy__send_message') as mock:
            pos = rpp.get_placement(state)
            mock.assert_called_with(expected_client_request)
            self.assertEqual(pos, Position(0, 1))
示例#14
0
    def test_can_tournament_run(self):
        # Dummy socket can be used because we aren't running the tournament
        self.dummy_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.rp1 = RemotePlayerProxy('a', 1.0, self.dummy_sock)
        self.rp2 = RemotePlayerProxy('b', 2.0, self.dummy_sock)
        self.rp3 = RemotePlayerProxy('c', 3.0, self.dummy_sock)
        self.rp4 = RemotePlayerProxy('d', 4.0, self.dummy_sock)

        server = Server()
        server._Server__remote_player_proxies = [
            self.rp1, self.rp2, self.rp3, self.rp4
        ]
        self.assertFalse(server._Server__can_tournament_run())

        self.rp5 = RemotePlayerProxy('e', 5.0, self.dummy_sock)
        server._Server__remote_player_proxies.append(self.rp5)
        self.assertTrue(server._Server__can_tournament_run())
        self.__server_close(server)
示例#15
0
class RemoteContractProxy():
    def __init__(self, connection):
        """
		This class implements a remote player proxy contract which
		has the same interface as the player, but checks
		the sent and received messages for validity.
		"""
        self.name = None
        self.remote_player_proxy = RemotePlayerProxy(connection)

    def register(self):
        p_name = self.remote_player_proxy.register()
        self.name = p_name
        return p_name

    def receive_stone(self, stone_type):
        self.remote_player_proxy.receive_stone(stone_type)

    def choose_move(self, boards):
        try:
            p_move = self.remote_player_proxy.choose_move(boards)
            p_move = p_move.replace("\"", "")
            if p_move == PASS:
                return PASS
            else:
                move_point = str_to_point(p_move)
                return (move_point.x, move_point.y)
        except PointException:
            raise PointException("Invalid move.")

    def game_over(self, end_tag):
        try:
            response = self.remote_player_proxy.game_over(end_tag)
            response = response.replace("\"", "")
            return (response == GAME_OVER_RESPONSE)
        except:
            return False
示例#16
0
    def __run_signup_period(self):
        """
        This function conducts a single "waiting period" where we sign up players for a tournament throughn the server
        socket. It looks for new connections on our TCP server socket, and will add any client socket connections
        to our self._remote_player_proxies array. This function will wait for signups for self._signup_timeout 
        seconds before returning.
        """
        # get time in self._signup_timeout seconds from now
        time_end = time.time() + self.__signup_timeout

        # loop until we reach that time (i.e. this loop will run for signup_timeout seconds)
        while time.time() < time_end:
            client_sock = None
            try:
                (client_sock, address) = self.__server_socket.accept()
                client_sock.settimeout(self.NAME_TIMEOUT)

                # Receive name from client
                data = client_sock.recv(4096)

                name = data.decode('ascii')

                if name:
                    # client timeout is now handled by the referee
                    client_sock.settimeout(None)
                    # Initialize the remote proxy player with the client socket
                    curr_time = time.time()
                    rpp = RemotePlayerProxy(name, curr_time, client_sock)
                    self.__remote_player_proxies.append(rpp)
                else:
                    # Either did not provide name, or provided a taken name, so we disconnect them
                    client_sock.close()

                # If we have reached the max number of clients, stop listening
                if len(self.__remote_player_proxies) == self.__max_clients:
                    break
            except Exception:
                if client_sock:
                    client_sock.close()

        self.__signup_periods -= 1
示例#17
0
 def test_init_fail5(self):
     # Tests failing init due to name that is too long
     with self.assertRaises(ValueError):
         RemotePlayerProxy("thisstringistoolong", 2.0, self.sock1)
示例#18
0
 def test_init_fail4(self):
     # Tests failing init due to empty name
     with self.assertRaises(ValueError):
         RemotePlayerProxy("", 2.0, self.sock1)
示例#19
0
 def test_init_fail3(self):
     # Tests failing init due to invalid socket
     with self.assertRaises(TypeError):
         RemotePlayerProxy("name", 10.0, ["not a socket"])
示例#20
0
 def test_init_fail2(self):
     # Tests failing init due to invalid age
     with self.assertRaises(TypeError):
         RemotePlayerProxy("name", "not a float")
示例#21
0
 def test_init_fail1(self):
     # Tests failing init due to invalid name
     with self.assertRaises(TypeError):
         RemotePlayerProxy({'not a str': 'duh'})
示例#22
0
 def test_is_ack_false2(self):
     # Tests an invalid ack
     rpp = RemotePlayerProxy('name', 1.0, self.dummy_socket)
     is_ack = rpp._RemotePlayerProxy__is_ack([])
     self.assertFalse(is_ack)
示例#23
0
 def test_is_ack_true(self):
     # Tests a valid ack
     rpp = RemotePlayerProxy('name', 1.0, self.dummy_socket)
     is_ack = rpp._RemotePlayerProxy__is_ack(['void'])
     self.assertTrue(is_ack)
示例#24
0
 def test_sync(self):
     # Tests that we simply return None for sync
     rpp = RemotePlayerProxy('name', 1.0, self.dummy_socket)
     state = State(self.__b, players=[self.__p1, self.__p2, self.__p3])
     res = rpp.sync(state)
     self.assertEquals(res, None)
示例#25
0
 def test_game_over(self):
     # Test that we simply return None for game_over
     rpp = RemotePlayerProxy('name', 1.0, self.dummy_socket)
     res = rpp.game_over([], [], [])
     self.assertEquals(res, None)
示例#26
0
 def test_receive_messages_lost_connection(self):
     # Tests that a remote proxy player can successfully receive a message from a client
     rpp = RemotePlayerProxy('name', 1.0, self.dummy_socket)
     response = rpp._RemotePlayerProxy__receive_messages()
     self.assertEqual(response, [])
示例#27
0
 def test_kick_success(self):
     # Test that kicking the player sets their internal state to kicked, and returns None
     rpp = RemotePlayerProxy('name', 1.0, self.dummy_socket)
     res = rpp.kick('test')
     self.assertTrue(rpp.kicked)
     self.assertEquals(res, None)