fix: two-player lobby deadlock

This commit is contained in:
2026-08-30 23:42:26 +03:00
parent d5eb26d330
commit 93af738e36
9 changed files with 77 additions and 10 deletions
+38
View File
@@ -151,8 +151,46 @@ static void test_human_game_journey(void) {
assert(application.lifecycle.game.state.phase == PHASE_LOBBY);
}
static void test_atomic_two_player_lobby(void) {
test_random_t random = {.value = 91U};
application_t application;
application_init(&application, (random_source_t){.next_u32 = next_random, .context = &random});
http_api_t api;
http_api_init(&api, &application);
http_api_response_t response = call(&api, HTTP_API_ROUTE_JOIN, HTTP_API_POST,
"{\"name\":\"Алиса\",\"requestedRole\":\"player\"}", NULL);
assert(response.status == 200U && strstr(response.body, "\"role\":\"player1\"") != NULL);
char player_1[33]; token_from_response(&response, player_1);
response = call(&api, HTTP_API_ROUTE_JOIN, HTTP_API_POST,
"{\"name\":\"Борис\",\"requestedRole\":\"player\"}", NULL);
assert(response.status == 200U && strstr(response.body, "\"role\":\"player2\"") != NULL);
char player_2[33]; token_from_response(&response, player_2);
const uint32_t game_id = application.lifecycle.game.state.game_id;
response = call(&api, HTTP_API_ROUTE_STATE, HTTP_API_GET, NULL, player_1);
assert(response.status == 200U && strstr(response.body, "\"viewer\":\"player1\"") != NULL && strstr(response.body, "Алиса") != NULL && strstr(response.body, "Борис") != NULL);
response = call(&api, HTTP_API_ROUTE_STATE, HTTP_API_GET, NULL, player_2);
assert(response.status == 200U && strstr(response.body, "\"viewer\":\"player2\"") != NULL);
char config[96];
snprintf(config, sizeof(config), "{\"token\":\"%s\",\"gameId\":%u,\"mode\":\"human\"}", player_2, (unsigned int)game_id);
response = call(&api, HTTP_API_ROUTE_CONFIG, HTTP_API_POST, config, NULL);
assert(response.status == 403U);
char start[80]; snprintf(start, sizeof(start), "{\"token\":\"%s\",\"gameId\":%u}", player_2, (unsigned int)game_id);
response = call(&api, HTTP_API_ROUTE_START, HTTP_API_POST, start, NULL); assert(response.status == 403U);
snprintf(config, sizeof(config), "{\"token\":\"%s\",\"gameId\":%u,\"mode\":\"human\"}", player_1, (unsigned int)game_id);
response = call(&api, HTTP_API_ROUTE_CONFIG, HTTP_API_POST, config, NULL); assert(response.status == 200U);
response = call(&api, HTTP_API_ROUTE_START, HTTP_API_POST, start, NULL); assert(response.status == 403U);
snprintf(start, sizeof(start), "{\"token\":\"%s\",\"gameId\":%u}", player_1, (unsigned int)game_id);
response = call(&api, HTTP_API_ROUTE_START, HTTP_API_POST, start, NULL); assert(response.status == 200U && application.lifecycle.game.state.phase == PHASE_IN_PROGRESS);
response = call(&api, HTTP_API_ROUTE_LEAVE, HTTP_API_POST, (snprintf(start, sizeof(start), "{\"token\":\"%s\",\"gameId\":%u}", player_2, (unsigned int)game_id), start), NULL);
assert(response.status == 200U && !application.lifecycle.sessions.entries[1].occupied);
response = call(&api, HTTP_API_ROUTE_JOIN, HTTP_API_POST, "{\"name\":\"Вера\",\"requestedRole\":\"player\"}", NULL);
assert(response.status == 200U && strstr(response.body, "\"role\":\"player2\"") != NULL);
resume(&api, player_1, "player1");
}
int main(void) {
test_human_game_journey();
test_atomic_two_player_lobby();
puts("human game integration tests passed");
return 0;
}