Add tests for restoring the presence state after a restart. (#16151)
parent
19a1cda084
commit
da162cbe4e
|
@ -1 +1 @@
|
|||
Clean-up calling `setup_background_tasks` in unit tests.
|
||||
Improve presence tests.
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Improve presence tests.
|
|
@ -38,6 +38,7 @@ from synapse.handlers.presence import (
|
|||
from synapse.rest import admin
|
||||
from synapse.rest.client import room
|
||||
from synapse.server import HomeServer
|
||||
from synapse.storage.database import LoggingDatabaseConnection
|
||||
from synapse.types import JsonDict, UserID, get_domain_from_id
|
||||
from synapse.util import Clock
|
||||
|
||||
|
@ -513,6 +514,121 @@ class PresenceTimeoutTestCase(unittest.TestCase):
|
|||
self.assertEqual(state, new_state)
|
||||
|
||||
|
||||
class PresenceHandlerInitTestCase(unittest.HomeserverTestCase):
|
||||
def default_config(self) -> JsonDict:
|
||||
config = super().default_config()
|
||||
# Disable background tasks on this worker so that the PresenceHandler isn't
|
||||
# loaded until we request it.
|
||||
config["run_background_tasks_on"] = "other"
|
||||
return config
|
||||
|
||||
def prepare(self, reactor: MemoryReactor, clock: Clock, hs: HomeServer) -> None:
|
||||
self.user_id = f"@test:{self.hs.config.server.server_name}"
|
||||
|
||||
# Move the reactor to the initial time.
|
||||
self.reactor.advance(1000)
|
||||
now = self.clock.time_msec()
|
||||
|
||||
main_store = hs.get_datastores().main
|
||||
self.get_success(
|
||||
main_store.update_presence(
|
||||
[
|
||||
UserPresenceState(
|
||||
user_id=self.user_id,
|
||||
state=PresenceState.ONLINE,
|
||||
last_active_ts=now,
|
||||
last_federation_update_ts=now,
|
||||
last_user_sync_ts=now,
|
||||
status_msg=None,
|
||||
currently_active=True,
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
# Regenerate the preloaded presence information on PresenceStore.
|
||||
def refill_presence(db_conn: LoggingDatabaseConnection) -> None:
|
||||
main_store._presence_on_startup = main_store._get_active_presence(db_conn)
|
||||
|
||||
self.get_success(main_store.db_pool.runWithConnection(refill_presence))
|
||||
|
||||
def test_restored_presence_idles(self) -> None:
|
||||
"""The presence state restored from the database should not persist forever."""
|
||||
|
||||
# Get the handler (which kicks off a bunch of timers).
|
||||
presence_handler = self.hs.get_presence_handler()
|
||||
|
||||
# Assert the user is online.
|
||||
state = self.get_success(
|
||||
presence_handler.get_state(UserID.from_string(self.user_id))
|
||||
)
|
||||
self.assertEqual(state.state, PresenceState.ONLINE)
|
||||
|
||||
# Advance such that the user should timeout.
|
||||
self.reactor.advance(SYNC_ONLINE_TIMEOUT / 1000)
|
||||
self.reactor.pump([5])
|
||||
|
||||
# Check that the user is now offline.
|
||||
state = self.get_success(
|
||||
presence_handler.get_state(UserID.from_string(self.user_id))
|
||||
)
|
||||
self.assertEqual(state.state, PresenceState.OFFLINE)
|
||||
|
||||
@parameterized.expand(
|
||||
[
|
||||
(PresenceState.BUSY, PresenceState.BUSY),
|
||||
(PresenceState.ONLINE, PresenceState.ONLINE),
|
||||
(PresenceState.UNAVAILABLE, PresenceState.UNAVAILABLE),
|
||||
# Offline syncs don't update the state.
|
||||
(PresenceState.OFFLINE, PresenceState.ONLINE),
|
||||
]
|
||||
)
|
||||
@unittest.override_config({"experimental_features": {"msc3026_enabled": True}})
|
||||
def test_restored_presence_online_after_sync(
|
||||
self, sync_state: str, expected_state: str
|
||||
) -> None:
|
||||
"""
|
||||
The presence state restored from the database should be overridden with sync after a timeout.
|
||||
|
||||
Args:
|
||||
sync_state: The presence state of the new sync.
|
||||
expected_state: The expected presence right after the sync.
|
||||
"""
|
||||
|
||||
# Get the handler (which kicks off a bunch of timers).
|
||||
presence_handler = self.hs.get_presence_handler()
|
||||
|
||||
# Assert the user is online, as restored.
|
||||
state = self.get_success(
|
||||
presence_handler.get_state(UserID.from_string(self.user_id))
|
||||
)
|
||||
self.assertEqual(state.state, PresenceState.ONLINE)
|
||||
|
||||
# Advance slightly and sync.
|
||||
self.reactor.advance(SYNC_ONLINE_TIMEOUT / 1000 / 2)
|
||||
self.get_success(
|
||||
presence_handler.user_syncing(
|
||||
self.user_id, sync_state != PresenceState.OFFLINE, sync_state
|
||||
)
|
||||
)
|
||||
|
||||
# Assert the user is in the expected state.
|
||||
state = self.get_success(
|
||||
presence_handler.get_state(UserID.from_string(self.user_id))
|
||||
)
|
||||
self.assertEqual(state.state, expected_state)
|
||||
|
||||
# Advance such that the user's preloaded data times out, but not the new sync.
|
||||
self.reactor.advance(SYNC_ONLINE_TIMEOUT / 1000 / 2)
|
||||
self.reactor.pump([5])
|
||||
|
||||
# Check that the user is in the sync state (as the client is currently syncing still).
|
||||
state = self.get_success(
|
||||
presence_handler.get_state(UserID.from_string(self.user_id))
|
||||
)
|
||||
self.assertEqual(state.state, sync_state)
|
||||
|
||||
|
||||
class PresenceHandlerTestCase(BaseMultiWorkerStreamTestCase):
|
||||
user_id = "@test:server"
|
||||
user_id_obj = UserID.from_string(user_id)
|
||||
|
|
Loading…
Reference in New Issue