Skip to content

Commit

Permalink
Issue/#752 queue state track (#754)
Browse files Browse the repository at this point in the history
* Add failing test example

* Only reset state for players who did not get `game_launch`
  • Loading branch information
Askaholic authored Apr 1, 2021
1 parent 9e3d47e commit 1c93e8d
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 16 deletions.
7 changes: 2 additions & 5 deletions server/ladder_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,10 +373,6 @@ async def start_game(
all_players = team1 + team2
all_guests = all_players[1:]

host.state = PlayerState.HOSTING
for guest in all_guests:
guest.state = PlayerState.JOINING

played_map_ids = await self.get_game_history(
all_players,
queue.id,
Expand Down Expand Up @@ -475,7 +471,8 @@ def game_options(player: Player) -> GameLaunchOptions:

msg = {"command": "match_cancelled"}
for player in all_players:
player.state = PlayerState.IDLE
if player.state == PlayerState.STARTING_AUTOMATCH:
player.state = PlayerState.IDLE
player.write_message(msg)

async def get_game_history(
Expand Down
72 changes: 69 additions & 3 deletions tests/integration_tests/test_matchmaker.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,27 @@ async def test_game_matchmaking_timeout(lobby_server, game_service):
)
assert game_service._games == {}

# Player's state is reset so they are able to queue again
# Player's state is reset once they leave the game
await proto1.send_message({
"command": "GameState",
"target": "game",
"args": ["Ended"]
})
await proto1.send_message({
"command": "game_matchmaking",
"state": "start",
"faction": "uef"
})
await read_until_command(proto1, "search_info", state="start", timeout=5)

# And not before they've left the game
await proto2.send_message({
"command": "game_matchmaking",
"state": "start",
"faction": "uef"
})
await read_until_command(proto1, "search_info", state="start", timeout=15)
with pytest.raises(asyncio.TimeoutError):
await read_until_command(proto2, "search_info", state="start", timeout=5)


@fast_forward(120)
Expand Down Expand Up @@ -182,14 +196,28 @@ async def test_game_matchmaking_timeout_guest(lobby_server, game_service):
)
assert game_service._games == {}

# Player's state is reset so they are able to queue again
# Player's state is reset once they leave the game
await proto1.send_message({
"command": "GameState",
"target": "game",
"args": ["Ended"]
})
await proto1.send_message({
"command": "game_matchmaking",
"state": "start",
"faction": "uef"
})
await read_until_command(proto1, "search_info", state="start", timeout=5)

# And not before they've left the game
await proto2.send_message({
"command": "game_matchmaking",
"state": "start",
"faction": "uef"
})
with pytest.raises(asyncio.TimeoutError):
await read_until_command(proto2, "search_info", state="start", timeout=5)


@fast_forward(15)
async def test_game_matchmaking_cancel(lobby_server):
Expand Down Expand Up @@ -234,6 +262,44 @@ async def test_game_matchmaking_disconnect(lobby_server):
assert msg == {"command": "match_cancelled"}


@fast_forward(130)
async def test_game_matchmaking_close_fa_and_requeue(lobby_server):
proto1, proto2 = await queue_players_for_matchmaking(lobby_server)

_, _ = await asyncio.gather(
client_response(proto1),
client_response(proto2)
)
# Players can't connect to eachother, so one of them abandons the game and
# joins the queue again
await proto1.send_message({
"command": "GameState",
"target": "game",
"args": ["Ended"]
})
await proto1.send_message({
"command": "game_matchmaking",
"state": "start",
"queue": "ladder1v1"
})
await read_until_command(proto1, "search_info", state="start", timeout=5)

# The other player waits for the game to time out and then queues again
await read_until_command(proto2, "match_cancelled", timeout=120)
await proto2.send_message({
"command": "GameState",
"target": "game",
"args": ["Ended"]
})
await proto2.send_message({
"command": "game_matchmaking",
"state": "start",
"queue": "ladder1v1"
})

await read_until_command(proto1, "match_found", timeout=5)


@fast_forward(10)
async def test_matchmaker_info_message(lobby_server, mocker):
mocker.patch("server.matchmaker.pop_timer.time", return_value=1_562_000_000)
Expand Down
37 changes: 33 additions & 4 deletions tests/integration_tests/test_teammatchmaker.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ async def test_newbie_matchmaking_with_parties(lobby_server):
assert msg["map_position"] in (1, 2, 3, 4)


@fast_forward(60)
@fast_forward(120)
async def test_game_matchmaking_multiqueue_timeout(lobby_server):
protos, _ = await connect_players(lobby_server)

Expand All @@ -306,6 +306,7 @@ async def test_game_matchmaking_multiqueue_timeout(lobby_server):
})
for proto in protos
])
await read_until_command(protos[1], "search_info", state="start")
msg = await read_until_command(
protos[0],
"search_info",
Expand All @@ -316,7 +317,12 @@ async def test_game_matchmaking_multiqueue_timeout(lobby_server):
# Don't send any GPGNet messages so the match times out
await read_until_command(protos[0], "match_cancelled", timeout=120)

# Player's state is reset so they are able to queue again
# Player's state is reset once they leave the game
await protos[0].send_message({
"command": "GameState",
"target": "game",
"args": ["Ended"]
})
await protos[0].send_message({
"command": "game_matchmaking",
"state": "start",
Expand All @@ -330,6 +336,15 @@ async def test_game_matchmaking_multiqueue_timeout(lobby_server):
timeout=5
)

# And not before they've left the game
await protos[1].send_message({
"command": "game_matchmaking",
"state": "start",
"faction": "uef"
})
with pytest.raises(asyncio.TimeoutError):
await read_until_command(protos[1], "search_info", state="start", timeout=5)


@fast_forward(60)
async def test_game_matchmaking_multiqueue_multimatch(lobby_server):
Expand Down Expand Up @@ -395,7 +410,7 @@ def other_cancelled(msg):
assert msg1["state"] == "stop"


@fast_forward(60)
@fast_forward(120)
async def test_game_matchmaking_timeout(lobby_server):
protos, _ = await queue_players_for_matchmaking(lobby_server)

Expand All @@ -404,7 +419,12 @@ async def test_game_matchmaking_timeout(lobby_server):
read_until_command(proto, "match_cancelled", timeout=120) for proto in protos
])

# Player's state is reset so they are able to queue again
# Player's state is reset once they leave the game
await protos[0].send_message({
"command": "GameState",
"target": "game",
"args": ["Ended"]
})
await protos[0].send_message({
"command": "game_matchmaking",
"state": "start",
Expand All @@ -418,6 +438,15 @@ async def test_game_matchmaking_timeout(lobby_server):
timeout=5
)

# And not before they've left the game
await protos[1].send_message({
"command": "game_matchmaking",
"state": "start",
"faction": "uef"
})
with pytest.raises(asyncio.TimeoutError):
await read_until_command(protos[1], "search_info", state="start", timeout=5)


@fast_forward(60)
async def test_game_ratings(lobby_server):
Expand Down
9 changes: 5 additions & 4 deletions tests/unit_tests/test_ladder_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ async def test_start_game_1v1(
game = game_service[game_service.game_id_counter]

assert player1.lobby_connection.launch_game.called
# TODO: Once client supports `game_launch_timeout` change this to `assert not ...`
# TODO: Once client supports `match_cancelled` change this to `assert not`
assert player2.lobby_connection.launch_game.called
assert isinstance(game, LadderGame)
assert game.rating_type == queue.rating_type
Expand All @@ -159,10 +159,11 @@ async def test_start_game_timeout(
p1.lobby_connection.write.assert_called_once_with({"command": "match_cancelled"})
p2.lobby_connection.write.assert_called_once_with({"command": "match_cancelled"})
assert p1.lobby_connection.launch_game.called
# TODO: Once client supports `match_cancelled` change this to `assert not ...`
# TODO: Once client supports `match_cancelled` change this to `assert not`
# and uncomment the following lines.
assert p2.lobby_connection.launch_game.called
assert p1.state is PlayerState.IDLE
assert p2.state is PlayerState.IDLE
# assert p1.state is PlayerState.IDLE
# assert p2.state is PlayerState.IDLE


@given(
Expand Down

0 comments on commit 1c93e8d

Please sign in to comment.