Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Perform client time sync on login #1004

Merged
merged 17 commits into from
Feb 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions server/lobbyconnection.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import server.metrics as metrics
from server.db import FAFDatabase
from server.timing import datetime_now

from .config import TRACE, config
from .db.models import (
Expand Down Expand Up @@ -693,6 +694,7 @@ async def on_player_login(
await self.send({
"command": "welcome",
"me": self.player.to_dict(),
"current_time": datetime_now().isoformat(),

# For backwards compatibility for old clients. For now.
"id": self.player.id,
Expand Down
32 changes: 32 additions & 0 deletions tests/integration_tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import asyncio
import datetime
import hashlib
import json
import logging
Expand Down Expand Up @@ -240,6 +241,37 @@ def lobby_contexts_proxy(lobby_setup_proxy):
return contexts


@pytest.fixture
def fixed_time(monkeypatch):
"""
Fixture to fix server.timing value. By default, fixes all timings at 1970-01-01T00:00:00+00:00. Additionally, returned function can be called unbound times to change timing value, e.g.:

def test_time(fixed_time):
assert server.lobbyconnection.datetime_now().timestamp == 0.
fixed_time(1)
assert server.lobbyconnection.datetime_now().timestamp == 1.
"""

def fix_time(iso_utc_time: str | float | int | datetime.datetime = 0):
"""
Fix server.timing value.

:param iso_utc_time: UTC time to use. Can be isoformat, timestamp or native object.
"""
if isinstance(iso_utc_time, str):
iso_utc_time = datetime.datetime.fromisoformat(iso_utc_time)
elif isinstance(iso_utc_time, (float, int)):
iso_utc_time = datetime.datetime.fromtimestamp(iso_utc_time, datetime.timezone.utc)

def mock_datetime_now() -> datetime:
return iso_utc_time

monkeypatch.setattr("server.lobbyconnection.datetime_now", mock_datetime_now)

fix_time()
return fix_time


# TODO: This fixture is poorly named since it returns a ServerContext, however,
# it is used in almost every tests, so renaming it is a large task.
@pytest.fixture(params=("qstream", "json"))
Expand Down
12 changes: 8 additions & 4 deletions tests/integration_tests/test_login.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ async def test_server_ban_revoked_or_expired(lobby_server, user):
assert msg["login"] == user


async def test_server_login_valid(lobby_server):
async def test_server_login_valid(lobby_server, fixed_time):
proto = await connect_client(lobby_server)
await perform_login(proto, ("Rhiza", "puff_the_magic_dragon"))
msg = await proto.read_message()
Expand All @@ -118,6 +118,7 @@ async def test_server_login_valid(lobby_server):
assert msg == {
"command": "welcome",
"me": me,
"current_time": "1970-01-01T00:00:00+00:00",
"id": 3,
"login": "Rhiza"
}
Expand All @@ -137,7 +138,7 @@ async def test_server_login_valid(lobby_server):
}


async def test_server_login_valid_admin(lobby_server):
async def test_server_login_valid_admin(lobby_server, fixed_time):
proto = await connect_client(lobby_server)
await perform_login(proto, ("test", "test_password"))
msg = await proto.read_message()
Expand All @@ -163,6 +164,7 @@ async def test_server_login_valid_admin(lobby_server):
assert msg == {
"command": "welcome",
"me": me,
"current_time": "1970-01-01T00:00:00+00:00",
"id": 1,
"login": "test"
}
Expand All @@ -182,7 +184,7 @@ async def test_server_login_valid_admin(lobby_server):
}


async def test_server_login_valid_moderator(lobby_server):
async def test_server_login_valid_moderator(lobby_server, fixed_time):
proto = await connect_client(lobby_server)
await perform_login(proto, ("moderator", "moderator"))
msg = await proto.read_message()
Expand All @@ -207,6 +209,7 @@ async def test_server_login_valid_moderator(lobby_server):
assert msg == {
"command": "welcome",
"me": me,
"current_time": "1970-01-01T00:00:00+00:00",
"id": 20,
"login": "moderator"
}
Expand Down Expand Up @@ -261,7 +264,7 @@ async def test_server_login_double(lobby_server):
}


async def test_server_login_token_valid(lobby_server, jwk_priv_key, jwk_kid):
async def test_server_login_token_valid(lobby_server, jwk_priv_key, jwk_kid, fixed_time):
proto = await connect_client(lobby_server)
await proto.send_message({
"command": "auth",
Expand Down Expand Up @@ -305,6 +308,7 @@ async def test_server_login_token_valid(lobby_server, jwk_priv_key, jwk_kid):
assert msg == {
"command": "welcome",
"me": me,
"current_time": "1970-01-01T00:00:00+00:00",
"id": 3,
"login": "Rhiza"
}
Expand Down
Loading