Ejemplo n.º 1
0
async def test_cancel_twice(ladder_service: LadderService, player_factory):
    p1 = player_factory('Dostya',
                        player_id=1,
                        ladder_rating=(1500, 500),
                        ladder_games=0)
    p2 = player_factory('Brackman',
                        player_id=2,
                        ladder_rating=(2000, 500),
                        ladder_games=0)

    search = Search([p1])
    search2 = Search([p2])

    await ladder_service.start_search(p1, search, 'ladder1v1')
    await ladder_service.start_search(p2, search2, 'ladder1v1')

    searches = ladder_service._cancel_existing_searches(p1)
    assert search.is_cancelled
    assert searches == [search]
    assert not search2.is_cancelled

    searches = ladder_service._cancel_existing_searches(p1)
    assert searches == []

    searches = ladder_service._cancel_existing_searches(p2)
    assert search2.is_cancelled
    assert searches == [search2]
Ejemplo n.º 2
0
async def test_start_search_cancels_previous_search(
    ladder_service: LadderService,
    player_factory,
    event_loop
):
    p1 = player_factory(
        "Dostya",
        player_id=1,
        ladder_rating=(1500, 500),
        ladder_games=0,
        with_lobby_connection=True
    )

    ladder_service.start_search([p1], "ladder1v1")
    await exhaust_callbacks(event_loop)
    search1 = ladder_service._searches[p1]["ladder1v1"]

    assert p1.state == PlayerState.SEARCHING_LADDER
    assert search1 in ladder_service.queues["ladder1v1"]._queue

    ladder_service.start_search([p1], "ladder1v1")
    await exhaust_callbacks(event_loop)
    search2 = ladder_service._searches[p1]["ladder1v1"]

    assert p1.state == PlayerState.SEARCHING_LADDER
    assert search1.is_cancelled
    assert search1 not in ladder_service.queues["ladder1v1"]._queue
    assert search2 in ladder_service.queues["ladder1v1"]._queue
Ejemplo n.º 3
0
def test_inform_player(ladder_service: LadderService):
    p1 = mock.create_autospec(Player('Dostya', id=1))
    p1.ladder_rating = (1500, 500)

    ladder_service.inform_player(p1)

    assert p1.lobby_connection.sendJSON.called
Ejemplo n.º 4
0
async def test_start_game_called_on_match(ladder_service: LadderService, player_factory):
    p1 = player_factory(
        "Dostya",
        player_id=1,
        ladder_rating=(2300, 64),
        ladder_games=0,
        with_lobby_connection=True
    )
    p2 = player_factory(
        "QAI",
        player_id=2,
        ladder_rating=(2350, 125),
        ladder_games=0,
        with_lobby_connection=True
    )

    ladder_service.start_game = CoroutineMock()
    ladder_service.write_rating_progress = CoroutineMock()

    ladder_service.start_search([p1], "ladder1v1")
    ladder_service.start_search([p2], "ladder1v1")

    await asyncio.sleep(2)

    ladder_service.write_rating_progress.assert_called()
    ladder_service.start_game.assert_called_once()
Ejemplo n.º 5
0
def test_inform_player(ladder_service: LadderService):
    p1 = mock.create_autospec(Player("Dostya", id=1))
    p1.ladder_rating = (1500, 500)

    ladder_service.inform_player(p1)

    assert p1.lobby_connection.sendJSON.called
Ejemplo n.º 6
0
async def test_write_rating_progress_message_2(ladder_service: LadderService,
                                               player_factory):
    player = player_factory(ladder_rating=(1500, 400.1235))
    player.write_message = CoroutineMock()

    ladder_service.write_rating_progress(player, RatingType.LADDER_1V1)

    player.write_message.assert_called_once()
    assert player.write_message.call_args[0][0].get("command") == "notice"
    assert player.write_message.call_args[0][0].get("style") == "info"
    assert "40%" in player.write_message.call_args[0][0].get("text", "")
Ejemplo n.º 7
0
async def test_write_rating_progress_other_rating(
        ladder_service: LadderService, player_factory):
    player = player_factory(ladder_rating=(1500, 500),
                            global_rating=(1500, 400.1235))
    player.write_message = CoroutineMock()

    # There's no reason we would call it with global, but the logic is the same
    # and global is an available rating that's not ladder
    ladder_service.write_rating_progress(player, RatingType.GLOBAL)

    player.write_message.assert_called_once()
    assert player.write_message.call_args[0][0].get("command") == "notice"
    assert player.write_message.call_args[0][0].get("style") == "info"
    assert "40%" in player.write_message.call_args[0][0].get("text", "")
Ejemplo n.º 8
0
async def test_queue_initialization(database, game_service):
    ladder_service = LadderService(database, game_service)

    def make_mock_queue(*args, **kwargs):
        queue = create_autospec(MatchmakerQueue)
        queue.map_pools = {}
        return queue

    with mock.patch("server.ladder_service.MatchmakerQueue", make_mock_queue):
        for name in list(ladder_service.queues.keys()):
            ladder_service.queues[name] = make_mock_queue()

        await ladder_service.initialize()

        for queue in ladder_service.queues.values():
            queue.initialize.assert_called_once()
Ejemplo n.º 9
0
async def test_cancel_all_searches(ladder_service: LadderService,
                                   player_factory, event_loop):
    p1 = player_factory(login="******", player_id=1, ladder_rating=(1500, 500), ladder_games=0)

    ladder_service.start_search([p1], "ladder1v1")
    await exhaust_callbacks(event_loop)
    search = ladder_service._searches[p1]["ladder1v1"]

    assert p1.state == PlayerState.SEARCHING_LADDER
    assert search in ladder_service.queues["ladder1v1"]._queue
    assert not search.is_cancelled

    ladder_service.cancel_search(p1)

    assert p1.state == PlayerState.IDLE
    assert search.is_cancelled
    assert "ladder1v1" not in ladder_service._searches[p1]
Ejemplo n.º 10
0
async def test_start_search_multiqueue_multiple_players(
    ladder_service: LadderService,
    player_factory,
    queue_factory,
    event_loop
):
    ladder_service.queues["tmm2v2"] = queue_factory("tmm2v2")

    p1 = player_factory(
        "Dostya",
        player_id=1,
        ladder_rating=(1000, 10),
        with_lobby_connection=True
    )

    p2 = player_factory(
        "Brackman",
        player_id=2,
        ladder_rating=(1000, 10),
        with_lobby_connection=True
    )

    ladder_service.start_search([p1, p2], "ladder1v1")
    await exhaust_callbacks(event_loop)

    assert "ladder1v1" in ladder_service._searches[p1]
    assert "ladder1v1" in ladder_service._searches[p2]

    ladder_service.start_search([p1, p2], "tmm2v2")
    await exhaust_callbacks(event_loop)

    assert "ladder1v1" in ladder_service._searches[p1]
    assert "tmm2v2" in ladder_service._searches[p1]
    assert "ladder1v1" in ladder_service._searches[p2]
    assert "tmm2v2" in ladder_service._searches[p2]

    ladder_service.cancel_search(p1, "tmm2v2")
    await exhaust_callbacks(event_loop)

    assert "ladder1v1" in ladder_service._searches[p1]
    assert "tmm2v2" not in ladder_service._searches[p1]
    assert "ladder1v1" in ladder_service._searches[p2]
    assert "tmm2v2" not in ladder_service._searches[p2]

    ladder_service.cancel_search(p2, "ladder1v1")
    await exhaust_callbacks(event_loop)

    assert "ladder1v1" not in ladder_service._searches[p1]
    assert "tmm2v2" not in ladder_service._searches[p1]
    assert "ladder1v1" not in ladder_service._searches[p2]
    assert "tmm2v2" not in ladder_service._searches[p2]
Ejemplo n.º 11
0
async def test_write_rating_progress_message_2(
    ladder_service: LadderService,
    player_factory
):
    player = player_factory(ladder_rating=(1500, 400.1235))
    player.write_message = CoroutineMock()

    ladder_service.write_rating_progress(player, RatingType.LADDER_1V1)

    player.write_message.assert_called_once_with({
        "command": "notice",
        "style": "info",
        "text": (
            "The system is still learning you.<b><br><br>"
            "The learning phase is 40% complete<b>"
        )
    })
Ejemplo n.º 12
0
async def test_cancel_twice(ladder_service: LadderService, player_factory):
    p1 = player_factory(login="******", player_id=1, ladder_rating=(1500, 500), ladder_games=0)
    p2 = player_factory(login="******", player_id=2, ladder_rating=(2000, 500), ladder_games=0)

    ladder_service.start_search([p1], "ladder1v1")
    search = ladder_service._searches[p1]["ladder1v1"]
    ladder_service.start_search([p2], "ladder1v1")
    search2 = ladder_service._searches[p2]["ladder1v1"]

    ladder_service.cancel_search(p1)
    assert search.is_cancelled
    assert not search2.is_cancelled

    ladder_service.cancel_search(p1)

    ladder_service.cancel_search(p2)
    assert search2.is_cancelled
Ejemplo n.º 13
0
async def test_cancel_twice(ladder_service: LadderService):
    p1 = mock.create_autospec(Player('Dostya', id=1))
    p1.ladder_rating = (1500, 500)
    p1.numGames = 0

    p2 = mock.create_autospec(Player('Brackman', id=1))
    p2.ladder_rating = (2000, 50)
    p2.numGames = 0

    search = Search([p1])
    search2 = Search([p2])

    ladder_service.start_search(p1, search, 'ladder1v1')
    ladder_service.start_search(p2, search2, 'ladder1v1')

    searches = ladder_service._cancel_existing_searches(p1)
    assert search.is_cancelled
    assert searches == [search]
    assert not search2.is_cancelled

    searches = ladder_service._cancel_existing_searches(p1)
    assert searches == []

    searches = ladder_service._cancel_existing_searches(p2)
    assert search2.is_cancelled
    assert searches == [search2]
Ejemplo n.º 14
0
async def test_game_start_cancels_search(ladder_service: LadderService,
                                         player_factory, queue_factory,
                                         event_loop):
    ladder_service.queues["tmm2v2"] = queue_factory("tmm2v2")

    p1 = player_factory("Dostya",
                        player_id=1,
                        ladder_rating=(1000, 10),
                        with_lobby_connection=True)

    p2 = player_factory("Brackman",
                        player_id=2,
                        ladder_rating=(1000, 10),
                        with_lobby_connection=True)
    ladder_service.start_search([p1], "ladder1v1")
    ladder_service.start_search([p2], "ladder1v1")
    ladder_service.start_search([p1], "tmm2v2")
    ladder_service.start_search([p2], "tmm2v2")
    await exhaust_callbacks(event_loop)

    assert "ladder1v1" in ladder_service._searches[p1]
    assert "tmm2v2" in ladder_service._searches[p1]
    assert "ladder1v1" in ladder_service._searches[p2]
    assert "tmm2v2" in ladder_service._searches[p2]

    ladder_service.on_match_found(ladder_service._searches[p1]["ladder1v1"],
                                  ladder_service._searches[p2]["ladder1v1"],
                                  ladder_service.queues["ladder1v1"])

    assert "ladder1v1" not in ladder_service._searches[p1]
    assert "tmm2v2" not in ladder_service._searches[p1]
    assert "ladder1v1" not in ladder_service._searches[p2]
    assert "tmm2v2" not in ladder_service._searches[p2]
Ejemplo n.º 15
0
async def test_start_and_cancel_search(ladder_service: LadderService):
    p1 = mock.create_autospec(Player('Dostya', id=1))
    p1.ladder_rating = (1500, 500)
    p1.numGames = 0

    search = Search([p1])

    ladder_service.start_search(p1, search, 'ladder1v1')
    await asyncio.sleep(0)  # Give the other coro a chance to run

    assert p1.state == PlayerState.SEARCHING_LADDER
    assert ladder_service.queues['ladder1v1'].queue[search]
    assert not search.is_cancelled

    ladder_service.cancel_search(p1)

    assert p1.state == PlayerState.IDLE
    assert search.is_cancelled
Ejemplo n.º 16
0
async def test_start_game_called_on_match(ladder_service: LadderService):
    p1 = mock.create_autospec(Player('Dostya', id=1))
    p1.ladder_rating = (2300, 64)
    p1.numGames = 0

    p2 = mock.create_autospec(Player('QAI', id=4))
    p2.ladder_rating = (2350, 125)
    p2.numGames = 0

    ladder_service.start_game = CoroMock()
    ladder_service.inform_player = mock.Mock()

    ladder_service.start_search(p1, Search([p1]), 'ladder1v1')
    ladder_service.start_search(p2, Search([p2]), 'ladder1v1')

    await asyncio.sleep(1)

    ladder_service.inform_player.assert_called()
    ladder_service.start_game.assert_called_once()
Ejemplo n.º 17
0
async def test_write_rating_progress_message(ladder_service: LadderService,
                                             player_factory):
    player = player_factory(ladder_rating=(1500, 500))
    player.write_message = CoroutineMock()

    ladder_service.write_rating_progress(player, RatingType.LADDER_1V1)

    player.write_message.assert_called_once_with({
        "command":
        "notice",
        "style":
        "info",
        "text": ("<i>Welcome to the matchmaker</i><br><br><b>Until "
                 "you've played enough games for the system to learn "
                 "your skill level, you'll be matched randomly.</b><br>"
                 "Afterwards, you'll be more reliably matched up with "
                 "people of your skill level: so don't worry if your "
                 "first few games are uneven. This will improve as you "
                 "play!</b>")
    })
Ejemplo n.º 18
0
async def test_search_info_message(ladder_service: LadderService,
                                   player_factory, queue_factory, event_loop):
    ladder_service.queues["tmm2v2"] = queue_factory("tmm2v2")

    p1 = player_factory("Dostya",
                        player_id=1,
                        ladder_rating=(1000, 10),
                        with_lobby_connection=True)
    p1.write_message = CoroutineMock()
    p2 = player_factory("Rhiza",
                        player_id=2,
                        ladder_rating=(1000, 10),
                        with_lobby_connection=True)
    p2.write_message = CoroutineMock()

    ladder_service.start_search([p1, p2], "ladder1v1")
    await exhaust_callbacks(event_loop)

    msg = {
        "command": "search_info",
        "queue_name": "ladder1v1",
        "state": "start"
    }
    p1.write_message.assert_called_once_with(msg)
    p2.write_message.assert_called_once_with(msg)

    p1.write_message.reset_mock()
    p2.write_message.reset_mock()

    ladder_service.start_search([p1, p2], "tmm2v2")
    await exhaust_callbacks(event_loop)

    msg = {"command": "search_info", "queue_name": "tmm2v2", "state": "start"}
    p1.write_message.assert_called_once_with(msg)
    p2.write_message.assert_called_once_with(msg)

    p1.write_message.reset_mock()
    p2.write_message.reset_mock()
    ladder_service.cancel_search(p1)
    await exhaust_callbacks(event_loop)

    call_args = [
        mock.call({
            "command": "search_info",
            "queue_name": "ladder1v1",
            "state": "stop"
        }),
        mock.call({
            "command": "search_info",
            "queue_name": "tmm2v2",
            "state": "stop"
        }),
    ]

    assert p1.write_message.call_args_list == call_args
    assert p2.write_message.call_args_list == call_args
Ejemplo n.º 19
0
async def test_choose_map_all_maps_played(ladder_service: LadderService):
    ladder_service.get_ladder_history = CoroMock(return_value=[1, 2, 3])

    ladder_service.game_service.ladder_maps = [
        (1, "some_map", "maps/some_map.v001.zip"),
        (2, "some_map", "maps/some_map.v001.zip"),
        (3, "some_map", "maps/some_map.v001.zip"),
    ]

    chosen_map = await ladder_service.choose_map([None])

    assert chosen_map is not None
Ejemplo n.º 20
0
async def test_write_rating_progress_other_rating(
    ladder_service: LadderService,
    player_factory
):
    player = player_factory(
        ladder_rating=(1500, 500),
        global_rating=(1500, 400.1235)
    )
    player.write_message = CoroutineMock()

    # There's no reason we would call it with global, but the logic is the same
    # and global is an available rating that's not ladder
    ladder_service.write_rating_progress(player, RatingType.GLOBAL)

    player.write_message.assert_called_once_with({
        "command": "notice",
        "style": "info",
        "text": (
            "The system is still learning you.<b><br><br>"
            "The learning phase is 40% complete<b>"
        )
    })
Ejemplo n.º 21
0
async def test_start_game_called_on_match(ladder_service: LadderService,
                                          player_factory):
    p1 = player_factory('Dostya',
                        player_id=1,
                        ladder_rating=(2300, 64),
                        ladder_games=0,
                        with_lobby_connection=True)
    p2 = player_factory('QAI',
                        player_id=2,
                        ladder_rating=(2350, 125),
                        ladder_games=0,
                        with_lobby_connection=True)

    ladder_service.start_game = CoroutineMock()
    ladder_service.inform_player = CoroutineMock()

    await ladder_service.start_search(p1, Search([p1]), 'ladder1v1')
    await ladder_service.start_search(p2, Search([p2]), 'ladder1v1')

    await asyncio.sleep(2)

    ladder_service.inform_player.assert_called()
    ladder_service.start_game.assert_called_once()
Ejemplo n.º 22
0
async def test_start_search_cancels_previous_search(
        ladder_service: LadderService):
    p1 = mock.create_autospec(Player('Dostya', id=1))
    p1.ladder_rating = (1500, 500)
    p1.numGames = 0

    search1 = Search([p1])

    ladder_service.start_search(p1, search1, 'ladder1v1')
    await asyncio.sleep(0)  # Give the other coro a chance to run

    assert p1.state == PlayerState.SEARCHING_LADDER
    assert ladder_service.queues['ladder1v1'].queue[search1]

    search2 = Search([p1])

    ladder_service.start_search(p1, search2, 'ladder1v1')
    await asyncio.sleep(0)  # Give the other coro a chance to run

    assert p1.state == PlayerState.SEARCHING_LADDER
    assert search1.is_cancelled
    assert not ladder_service.queues['ladder1v1'].queue.get(search1)
    assert ladder_service.queues['ladder1v1'].queue[search2]
Ejemplo n.º 23
0
async def test_on_match_found_sets_player_state(ladder_service: LadderService,
                                                player_factory, event_loop):
    p1 = player_factory("Dostya",
                        player_id=1,
                        ladder_rating=(1000, 10),
                        with_lobby_connection=True)

    p2 = player_factory("Brackman",
                        player_id=2,
                        ladder_rating=(1000, 10),
                        with_lobby_connection=True)
    ladder_service.start_search([p1], "ladder1v1")
    ladder_service.start_search([p2], "ladder1v1")
    await exhaust_callbacks(event_loop)

    assert p1.state is PlayerState.SEARCHING_LADDER
    assert p2.state is PlayerState.SEARCHING_LADDER

    ladder_service.on_match_found(ladder_service._searches[p1]["ladder1v1"],
                                  ladder_service._searches[p2]["ladder1v1"],
                                  ladder_service.queues["ladder1v1"])

    assert p1.state is PlayerState.STARTING_AUTOMATCH
    assert p2.state is PlayerState.STARTING_AUTOMATCH
Ejemplo n.º 24
0
async def test_choose_map(ladder_service: LadderService):
    ladder_service.get_ladder_history = CoroMock(return_value=[1, 2, 3])

    ladder_service.game_service.ladder_maps = [
        (1, "some_map", "maps/some_map.v001.zip"),
        (2, "some_map", "maps/some_map.v001.zip"),
        (3, "some_map", "maps/some_map.v001.zip"),
        (4, "CHOOSE_ME", "maps/choose_me.v001.zip"),
    ]

    chosen_map = await ladder_service.choose_map([None])

    # Make the probability very low that the test passes because we got lucky
    for _ in range(20):
        assert chosen_map == (4, "CHOOSE_ME", "maps/choose_me.v001.zip")
Ejemplo n.º 25
0
def test_inform_player(ladder_service: LadderService):
    p1 = mock.create_autospec(Player('Dostya', id=1))
    p1.ladder_rating = (1500, 500)

    ladder_service.inform_player(p1)

    # Message is sent after the first call
    p1.lobby_connection.sendJSON.assert_called_once()
    ladder_service.inform_player(p1)
    p1.lobby_connection.sendJSON.reset_mock()
    # But not after the second
    p1.lobby_connection.sendJSON.assert_not_called()
    ladder_service.on_connection_lost(p1)
    ladder_service.inform_player(p1)

    # But it is called if the player relogs
    p1.lobby_connection.sendJSON.assert_called_once()
Ejemplo n.º 26
0
async def test_write_rating_progress(ladder_service: LadderService,
                                     player_factory):
    p1 = player_factory("Dostya",
                        player_id=1,
                        ladder_rating=(1500, 500),
                        with_lobby_connection=True)

    ladder_service.write_rating_progress(p1, RatingType.LADDER_1V1)
    # Message is sent after the first call
    p1.lobby_connection.write.assert_called_once()

    ladder_service.write_rating_progress(p1, RatingType.LADDER_1V1)
    p1.lobby_connection.write.reset_mock()
    # But not after the second
    p1.lobby_connection.write.assert_not_called()

    ladder_service.on_connection_lost(p1.lobby_connection)
    ladder_service.write_rating_progress(p1, RatingType.LADDER_1V1)
    # But it is called if the player relogs
    p1.lobby_connection.write.assert_called_once()
Ejemplo n.º 27
0
def ladder_service(game_service: GameService,
                   game_stats_service: GameStatsService):
    return LadderService(game_service, game_stats_service)