예제 #1
0
 def start_game(self, tiktok: Text, phone_number: Text, game_hashtag: Text):
     game_id = FirestoreDB.add_game(
         json_config_path=_TEST_FIRESTORE_INSTANCE_JSON_PATH,
         hashtag=game_hashtag)
     self._gamedb = FirestoreDB(
         json_config_path=_TEST_FIRESTORE_INSTANCE_JSON_PATH,
         game_id=game_id)
     self.join_game(tiktok=tiktok,
                    phone_number=phone_number,
                    game_id=game_id)
예제 #2
0
    def test_generate_tribes_count_initialization(
            self, algorithm_type, number_of_joined_players, game_options,
            expected_game_count_tribes, expected_game_count_teams,
            expected_game_count_players, expected_tribe_count_teams,
            expected_tribe_count_players, expected_team_count_players):
        # create a game
        game_id = FirestoreDB.add_game(
            json_config_path=_TEST_FIRESTORE_INSTANCE_JSON_PATH,
            hashtag='hashtag/foo')
        _gamedb._game_id = game_id

        # generate mock players with an id attribute and add the players to the game
        players = list()
        for i in range(0, number_of_joined_players):
            name = 'name/foo'
            tiktok = 'tiktok/bar'
            phone_number = f'+1000000000{i}'
            player = _gamedb.player(name=name,
                                    tiktok=tiktok,
                                    phone_number=phone_number)
            FirestoreDB.add_user(
                json_config_path=_TEST_FIRESTORE_INSTANCE_JSON_PATH,
                name=name,
                tiktok=tiktok,
                phone_number=phone_number)
            players.append(player)

        # read counts for game, all tribes, all teams and verify that they are correct
        game_info_dict = algorithm_type.generate_tribes(
            game_id=game_id,
            players=players,
            game_options=game_options,
            gamedb=_gamedb)

        game = _gamedb.game_from_id(game_id)
        self.assertEqual(game.count_tribes, expected_game_count_tribes)
        self.assertEqual(game.count_teams, expected_game_count_teams)
        self.assertEqual(game.count_players, expected_game_count_players)

        for tribe in game_info_dict['tribes']:
            tribe_ref = _gamedb.tribe_from_id(tribe.id)
            self.assertEqual(tribe_ref.count_teams, expected_tribe_count_teams)
            self.assertEqual(tribe_ref.count_players,
                             expected_tribe_count_players)
        for team in game_info_dict['teams']:
            self.assertEqual(
                _gamedb.team_from_id(team.id).count_players,
                expected_team_count_players)
예제 #3
0
    def test_integration(self):
        test_id = str(uuid.uuid4())
        # Inject a game ID (test uuid) into the gamedb. use a globally unique country code to ensure
        # that only this game gets scheduled.
        game_id = FirestoreDB.add_game(
            json_config_path=_TEST_FIRESTORE_INSTANCE_JSON_PATH,
            hashtag=_TEST_GAME_HASHTAG,
            country_code=f'US-{test_id}')
        gamedb = FirestoreDB(
            json_config_path=_TEST_FIRESTORE_INSTANCE_JSON_PATH,
            game_id=game_id)
        log_message(f'Running integration test for game {game_id}')

        # create an integration test subsystem log stream that specifically captures
        # game inputs and outputs at the SMS boundary.
        test_log_stream = GameIntegrationTestLogStream(game_id=game_id,
                                                       test_id=test_id)

        # add test challenges
        for challenge in _TEST_CHALLENGES:
            gamedb.add_challenge(challenge=challenge)

        # if non-existent, create users associated with players. NOTE: critical for FE code
        # to create users when players sign up.
        for player_info in [*_EMULATED_PLAYERS, *_REAL_PLAYERS]:
            FirestoreDB.add_user(
                json_config_path=_TEST_FIRESTORE_INSTANCE_JSON_PATH,
                name=player_info[0],
                tiktok=player_info[1],
                phone_number=player_info[2])

        # Inject players into gamedb. set the phone number of the players to a known, or emulated device.
        emulated_players = []
        for player_info in _EMULATED_PLAYERS:
            player = gamedb.player(name=player_info[0],
                                   tiktok=player_info[1],
                                   phone_number=player_info[2])
            emulated_players.append(
                EmulatedPlayer(id=player.id,
                               name=player.name,
                               tiktok=player.tiktok,
                               phone_number=player.phone_number,
                               test_stream=test_log_stream,
                               gamedb=gamedb))
        for player_info in _REAL_PLAYERS:
            player = gamedb.player(name=player_info[0],
                                   tiktok=player_info[1],
                                   phone_number=player_info[2])

        # mock the scheduling method in MM service so that we can force schedule
        # after initialization.
        save_check_start_time_fn = MatchmakerService._check_start_time
        check_start_time_fn = mock.MagicMock()
        check_start_time_fn.return_value = False
        MatchmakerService._check_start_time = check_start_time_fn

        # create device emulator for Twilio SMS events. patch this
        # into the game engine class for the test.
        notification_emulator = FakeTwilioSMSNotifier(
            json_config_path=_TEST_TWILIO_SMS_CONFIG_PATH,
            game_id=game_id,
            emulated_devices=emulated_players)
        build_notifier_fn = mock.MagicMock()
        build_notifier_fn.return_value = notification_emulator
        Engine._get_sms_notifier = build_notifier_fn

        # Instantiate a local matchmaker service. make sure all services have the right configs,
        # e.g. twilio should be using the prod service phone number so that it can actually send messages.
        # set the clock mode on (2) to async so that game events happen immediately during testing.
        service = MatchmakerService(
            matchmaker=MatchMakerRoundRobin(),
            region=f'US-{test_id}',
            gamedb=gamedb,
            game_options=GameOptions(
                game_clock_mode=GameClockMode.ASYNC,
                game_wait_sleep_interval_sec=_TEST_SLEEP_INTERVAL,
                multi_tribe_min_tribe_size=2,
                engine_worker_thread_count=5,
                tribe_council_time_sec=_TEST_SLEEP_INTERVAL))
        # mock the MM Twilio client
        service._get_sms_notifier = mock.MagicMock(
            return_value=notification_emulator)
        try:
            service.start_matchmaker_daemon(sleep_seconds=1)
            # force schedule the game in MM (1).
            check_start_time_fn.return_value = True
            MatchmakerService._check_start_time = check_start_time_fn
            while gamedb.game_from_id(game_id).count_players > 1:
                time.sleep(_TEST_SLEEP_INTERVAL)
        finally:
            MatchmakerService._check_start_time = save_check_start_time_fn
            service.set_stop()
            test_dict = test_log_stream.to_dict()
            if _SAVE_TEST_LOGS:
                persisted_test_logs = test_log_stream.persist()
                log_message(persisted_test_logs)
                with open(f'game_logs/stream.{test_id}.json', 'w+') as f:
                    f.write(persisted_test_logs)
            active_players = list()
            for player in gamedb.stream_players(
                    active_player_predicate_value=True):
                active_players.append(player)
            winner = active_players[0]
            found_winner_message = False
            for output in test_dict['outputs']:
                if 'You are the last survivor and WINNER' in output[
                        'message'] and output['name'] == winner.name:
                    found_winner_message = True
            self.assertTrue(found_winner_message)