예제 #1
0
    def test_password(self):
        # Second player to keep game alive after disconnect
        player_2 = 'PLAYER_2_{}_{}'.format(self.id(), self.test_start)
        player_2_conn = ServerConnection()
        num_players = 2
        self.login(game=self.game_name,
                   name=player_2,
                   connection=player_2_conn,
                   num_players=num_players)

        password = '******'
        wrong_password = '******'
        self.login(game=self.game_name,
                   password=password,
                   num_players=num_players)

        self.logout()
        self.reset_connection()

        message = self.login(game=self.game_name,
                             password=wrong_password,
                             num_players=num_players,
                             exp_result=Result.ACCESS_DENIED)
        self.assertIn('error', message)
        self.assertIn('Password mismatch', message['error'])

        self.login(game=self.game_name,
                   password=password,
                   num_players=num_players)
        self.logout()
        self.logout(connection=player_2_conn)
        player_2_conn.close()
예제 #2
0
    def test_one_username_two_connections_one_game(self):
        conn1 = ServerConnection()
        conn2 = ServerConnection()

        player1 = self.login(name=self.player_name,
                             game=self.game_name,
                             num_players=1,
                             connection=conn1)
        player2 = self.login(name=self.player_name,
                             game=self.game_name,
                             num_players=1,
                             connection=conn2)

        self.assertEqual(player1, player2)

        self.move_train(1, player1['trains'][0]['idx'], 1, connection=conn1)
        self.turn(connection=conn1)
        self.players_turn(connections=(
            conn1,
            conn2,
        ))

        player1 = self.get_player(connection=conn1)
        player2 = self.get_player(connection=conn2)

        self.assertEqual(player1, player2)

        conn1.close()
        conn2.close()
예제 #3
0
    def test_one_username_two_connections_different_games(self):
        conn1 = ServerConnection()
        conn2 = ServerConnection()
        game_name_1 = 'GAME_1_{}_{}'.format(self.id(), self.test_start)
        game_name_2 = 'GAME_2_{}_{}'.format(self.id(), self.test_start)

        player1 = self.login(name=self.player_name,
                             game=game_name_1,
                             num_players=1,
                             connection=conn1)
        player2 = self.login(name=self.player_name,
                             game=game_name_2,
                             num_players=1,
                             connection=conn2)

        self.assertEqual(len(player1['trains']), CONFIG.TRAINS_COUNT)
        self.assertEqual(len(player2['trains']), CONFIG.TRAINS_COUNT)

        self.move_train(1, player1['trains'][0]['idx'], 1, connection=conn1)
        self.turn(connection=conn1)

        player1 = self.get_player(connection=conn1)
        player2 = self.get_player(connection=conn2)

        self.assertEqual(player1['trains'][0]['line_idx'], 1)
        self.assertEqual(player1['trains'][0]['position'], 1)
        self.assertEqual(player1['rating'], 3060)

        self.assertEqual(player2['trains'][0]['line_idx'], 1)
        self.assertEqual(player2['trains'][0]['position'], 0)
        self.assertEqual(player2['rating'], 0)

        conn1.close()
        conn2.close()
예제 #4
0
    def test_game_writes_turns_on_ticks(self):
        """ Verify if game on server writes to replay.db on game's tick.
        """
        user_conn = ServerConnection()

        self.login(connection=user_conn)
        time.sleep(CONFIG.TICK_TIME + 1)  # Wait for game tick.
        self.logout(connection=user_conn)
        time.sleep(2)  # Wait for DB commit.

        games = self.observer()['games']
        self.assertIsNotNone(games)
        my_games = [g for g in games if self.player_name in g['name']]
        self.assertEqual(len(my_games), 1)
        self.assertGreater(my_games[0]['length'], 0)

        user_conn.close()
예제 #5
0
 def setUp(self):
     super().setUp()
     self.players = []
     for i in range(self.NUM_TOWNS):
         player_name = 'test_player_{}_{}_{}'.format(
             i, self.id(), self.test_start)
         conn = ServerConnection()
         player = AttrDict({'name': player_name, 'conn': conn})
         self.players.append(player)
예제 #6
0
    def test_reuse_player_name(self):
        # Second player
        player_2 = 'PLAYER_2_{}_{}'.format(self.id(), self.test_start)
        player_2_conn = ServerConnection()
        num_players = 2

        self.login(game=self.game_name,
                   name=player_2,
                   connection=player_2_conn,
                   num_players=num_players)
        self.login(game=self.game_name, num_players=num_players)
        self.players_turn([self.connection, player_2_conn])

        self.logout()
        self.reset_connection()
        self.logout(connection=player_2_conn)
        player_2_conn.close()

        player = self.login()
        self.assertEqual(player['rating'], 0)
        self.assertEqual(len(player['trains']), CONFIG.TRAINS_COUNT)
예제 #7
0
    def test_disconnect_and_login_to_the_same_game(self):
        # Second player to keep game alive after disconnect
        player_2 = 'PLAYER_2_{}_{}'.format(self.id(), self.test_start)
        player_2_conn = ServerConnection()
        num_players = 2

        self.login(game=self.game_name,
                   name=player_2,
                   connection=player_2_conn,
                   num_players=num_players)
        self.login(game=self.game_name, num_players=num_players)
        self.players_turn([self.connection, player_2_conn])
        player_before_disconnect = self.get_player()

        # Disconnect
        self.reset_connection()

        player_after_disconnect = self.login(game=self.game_name,
                                             num_players=num_players)
        self.assertEqual(player_before_disconnect, player_after_disconnect)

        self.logout()
        self.logout(connection=player_2_conn)
        player_2_conn.close()
예제 #8
0
 def connection(self):
     if self._connection is None:
         self._connection = ServerConnection()
     return self._connection
예제 #9
0
class BaseTest(unittest.TestCase):
    def __init__(self, *args, **kwargs):
        super(BaseTest, self).__init__(*args, **kwargs)
        self.test_start = datetime.now().strftime('%H:%M:%S.%f')
        self.player_name = 'PLAYER_{}_{}'.format(self.id(), self.test_start)
        self.game_name = 'GAME_{}_{}'.format(self.id(), self.test_start)
        self.current_tick = 0
        self._connection = None

    @classmethod
    def setUpClass(cls):
        cls.clear_db()

    @classmethod
    def tearDownClass(cls):
        cls.wait_for_finished_games()
        cls.clear_db()

    def tearDown(self):
        self.reset_connection()

    @staticmethod
    def clear_db():
        map_db.reset_db()

    @staticmethod
    def wait_for_finished_games(retries=10, period=1):
        with session_ctx() as db:
            for _ in range(retries):
                game = db.query(Game).filter(Game.data.is_(None)).first()
                if game:
                    time.sleep(period)
                else:
                    return True
            else:
                return False

    @property
    def connection(self):
        if self._connection is None:
            self._connection = ServerConnection()
        return self._connection

    @connection.setter
    def connection(self, value):
        self._connection = value

    def reset_connection(self):
        if self._connection is not None:
            self._connection.close()
            self._connection = None

    def do_action(self,
                  action,
                  data='',
                  exp_result=None,
                  is_raw=False,
                  connection=None,
                  **kwargs):
        connection = self.connection if connection is None else connection
        result, message = connection.send_action(action,
                                                 data,
                                                 is_raw=is_raw,
                                                 **kwargs)
        if exp_result is not None:
            self.assertEqual(exp_result, result)
        return result, message

    def login(self,
              name=None,
              game=None,
              password=None,
              num_players=None,
              num_turns=None,
              exp_result=Result.OKEY,
              **kwargs):
        message = {'name': self.player_name if name is None else name}
        if game is not None:
            message['game'] = game
        if password is not None:
            message['password'] = password
        if num_players is not None:
            message['num_players'] = num_players
        if num_turns is not None:
            message['num_turns'] = num_turns
        _, message = self.do_action(Action.LOGIN,
                                    message,
                                    exp_result=exp_result,
                                    **kwargs)
        return json.loads(message) if message else None

    def logout(self, exp_result=Result.OKEY, **kwargs):
        _, message = self.do_action(Action.LOGOUT,
                                    exp_result=exp_result,
                                    **kwargs)
        return json.loads(message) if message else None

    def turn(self, turns_count=1, exp_result=Result.OKEY, **kwargs):
        message = None
        for _ in range(turns_count):
            _, message = self.do_action(Action.TURN,
                                        exp_result=exp_result,
                                        **kwargs)
            if exp_result == Result.OKEY:
                self.current_tick += 1
        return json.loads(message) if message else None

    def get_map(self, layer, exp_result=Result.OKEY, **kwargs):
        _, message = self.do_action(Action.MAP, {'layer': layer},
                                    exp_result=exp_result,
                                    **kwargs)
        return json.loads(message)

    def move_train(self,
                   line_idx,
                   train_idx,
                   speed,
                   exp_result=Result.OKEY,
                   **kwargs):
        _, message = self.do_action(Action.MOVE, {
            'train_idx': train_idx,
            'line_idx': line_idx,
            'speed': speed,
        },
                                    exp_result=exp_result,
                                    **kwargs)
        return json.loads(message) if message else None

    def get_trains(self, **kwargs):
        map_data = self.get_map(1, **kwargs)
        return {x['idx']: x for x in map_data['trains']}

    def get_train(self, train_idx, **kwargs):
        trains = self.get_trains(**kwargs)
        self.assertIn(train_idx, trains)
        return trains[train_idx]

    def get_posts(self, **kwargs):
        map_data = self.get_map(1, **kwargs)
        return {x['idx']: x for x in map_data['posts']}

    def get_post(self, post_idx, **kwargs):
        posts = self.get_posts(**kwargs)
        self.assertIn(post_idx, posts)
        return posts[post_idx]

    def get_ratings(self, **kwargs):
        return self.get_map(1, **kwargs)['ratings']

    def get_train_line(self, train_idx, **kwargs):
        train = self.get_train(train_idx, **kwargs)
        return train['line_idx']

    def get_train_speed(self, train_idx, **kwargs):
        train = self.get_train(train_idx, **kwargs)
        return train['speed']

    def get_train_position(self, train_idx, **kwargs):
        train = self.get_train(train_idx, **kwargs)
        return train['position']

    @staticmethod
    def check_collision_event(events, ok_event):
        for event in events:
            if (event['type'] == ok_event.type
                    and event['train'] == ok_event.train
                    and event['tick'] == ok_event.tick):
                return True
        return False

    @staticmethod
    def check_refugees_arrival_event(events, ok_event):
        for event in events:
            if (event['type'] == ok_event.type
                    and event['refugees_number'] == ok_event.refugees_number
                    and event['tick'] == ok_event.tick):
                return True
        return False

    @staticmethod
    def check_hijackers_assault_event(events, ok_event):
        for event in events:
            if (event['type'] == ok_event.type
                    and event['hijackers_power'] == ok_event.hijackers_power
                    and event['tick'] == ok_event.tick):
                return True
        return False

    @staticmethod
    def check_parasites_assault_event(events, ok_event):
        for event in events:
            if (event['type'] == ok_event.type
                    and event['parasites_power'] == ok_event.parasites_power
                    and event['tick'] == ok_event.tick):
                return True
        return False

    def move_train_until_switch(self, next_line_idx, train_idx, speed,
                                **kwargs):
        self.move_train(next_line_idx, train_idx, speed, **kwargs)
        for _ in range(CONFIG.MAX_LINE_LENGTH):
            self.turn(**kwargs)
            if self.get_train_line(train_idx, **kwargs) == next_line_idx:
                break
        else:
            self.fail(
                'The train {} is not able to reach the line {} in {} turns'.
                format(train_idx, next_line_idx, CONFIG.MAX_LINE_LENGTH))

    def move_train_until_stop(self, line_idx, train_idx, speed, **kwargs):
        self.move_train(line_idx, train_idx, speed, **kwargs)
        for _ in range(CONFIG.MAX_LINE_LENGTH):
            self.turn(**kwargs)
            if self.get_train_speed(train_idx, **kwargs) == 0:
                break
        else:
            self.fail(
                'The train {} is not able to reach the end of line {} in {} turns'
                .format(train_idx, line_idx, CONFIG.MAX_LINE_LENGTH))

    def upgrade(self, posts=(), trains=(), exp_result=Result.OKEY, **kwargs):
        _, message = self.do_action(Action.UPGRADE, {
            'posts': posts,
            'trains': trains,
        },
                                    exp_result=exp_result,
                                    **kwargs)
        return json.loads(message) if message else None

    def get_player(self, exp_result=Result.OKEY, **kwargs):
        _, message = self.do_action(Action.PLAYER,
                                    exp_result=exp_result,
                                    **kwargs)
        return json.loads(message) if message else None

    def observer(self, exp_result=Result.OKEY, **kwargs):
        _, message = self.do_action(Action.OBSERVER,
                                    exp_result=exp_result,
                                    **kwargs)
        return json.loads(message) if message else None

    def set_turn(self, turn_idx, exp_result=Result.OKEY, **kwargs):
        _, message = self.do_action(Action.TURN, {'idx': turn_idx},
                                    exp_result=exp_result,
                                    **kwargs)
        return json.loads(message) if message else None

    def set_game(self, game_idx, exp_result=Result.OKEY, **kwargs):
        _, message = self.do_action(Action.GAME, {'idx': game_idx},
                                    exp_result=exp_result,
                                    **kwargs)
        return json.loads(message) if message else None

    def players_turn(self,
                     connections=(),
                     turns_count=1,
                     exp_result=Result.OKEY):
        for _ in range(turns_count):
            for conn in connections:
                self.turn_no_resp(conn)
            for conn in connections:
                self.turn_check_resp(conn, exp_result=exp_result)
            if exp_result == Result.OKEY:
                self.current_tick += 1

    def turn_no_resp(self, conn):
        self.turn(wait_for_response=False, connection=conn, exp_result=None)

    def turn_check_resp(self, conn, exp_result=Result.OKEY):
        result, message = conn.read_response()
        self.assertEqual(exp_result, result)
        return json.loads(message) if message else None

    def get_games(self, exp_result=Result.OKEY, **kwargs):
        _, message = self.do_action(Action.GAMES,
                                    exp_result=exp_result,
                                    **kwargs)
        return json.loads(message)