mirror of
https://github.com/element-hq/synapse
synced 2024-09-28 16:32:40 +00:00
Add some tests
This commit is contained in:
parent
af60f7b508
commit
bd49c3415b
2 changed files with 156 additions and 8 deletions
|
@ -18,7 +18,7 @@
|
|||
#
|
||||
#
|
||||
import logging
|
||||
from typing import TYPE_CHECKING, AbstractSet, Dict, List, Optional
|
||||
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple
|
||||
|
||||
from immutabledict import immutabledict
|
||||
|
||||
|
@ -197,7 +197,7 @@ class SlidingSyncHandler:
|
|||
# `["m.room.member", "$LAZY"]`
|
||||
filtered_room_map = sync_room_map
|
||||
# TODO: Apply sorts
|
||||
sorted_room_ids = await self.sort_rooms(filtered_room_map, to_token)
|
||||
sorted_room_info = await self.sort_rooms(filtered_room_map, to_token)
|
||||
|
||||
ops: List[SlidingSyncResult.SlidingWindowList.Operation] = []
|
||||
if list_config.ranges:
|
||||
|
@ -206,12 +206,17 @@ class SlidingSyncHandler:
|
|||
SlidingSyncResult.SlidingWindowList.Operation(
|
||||
op=OperationType.SYNC,
|
||||
range=range,
|
||||
room_ids=sorted_room_ids[range[0] : range[1]],
|
||||
room_ids=[
|
||||
room_id
|
||||
for room_id, rooms_for_user in sorted_room_info.items()[
|
||||
range[0] : range[1]
|
||||
]
|
||||
],
|
||||
)
|
||||
)
|
||||
|
||||
lists[list_key] = SlidingSyncResult.SlidingWindowList(
|
||||
count=len(sorted_room_ids),
|
||||
count=len(sorted_room_info),
|
||||
ops=ops,
|
||||
)
|
||||
|
||||
|
@ -485,15 +490,18 @@ class SlidingSyncHandler:
|
|||
self,
|
||||
sync_room_map: Dict[str, RoomsForUser],
|
||||
to_token: StreamToken,
|
||||
) -> List[str]:
|
||||
) -> List[Tuple[str, RoomsForUser]]:
|
||||
"""
|
||||
Sort by recency of the last event in the room (stream_ordering). In order to get
|
||||
Sort by stream_ordering of the last event in the room. In order to get
|
||||
a stable sort, we tie-break by room ID.
|
||||
|
||||
Args:
|
||||
sync_room_map: Dictionary of room IDs to sort along with membership
|
||||
information in the room at the time of `to_token`.
|
||||
to_token: We sort based on the events in the room at this token (<= `to_token`)
|
||||
|
||||
Returns:
|
||||
A sorted list of room IDs by stream_ordering along with membership information.
|
||||
"""
|
||||
|
||||
# Assemble a map of room ID to the `stream_ordering` of the last activity that the
|
||||
|
@ -523,7 +531,12 @@ class SlidingSyncHandler:
|
|||
last_activity_in_room_map[room_id] = room_for_user.event_pos.stream
|
||||
|
||||
return sorted(
|
||||
sync_room_map.keys(),
|
||||
sync_room_map.items(),
|
||||
# Sort by the last activity (stream_ordering) in the room, tie-break on room_id
|
||||
key=lambda room_id: (last_activity_in_room_map[room_id], room_id),
|
||||
key=lambda room_info: (
|
||||
last_activity_in_room_map[room_info[0]],
|
||||
room_info[0],
|
||||
),
|
||||
# We want descending order
|
||||
reverse=True,
|
||||
)
|
||||
|
|
|
@ -1113,3 +1113,138 @@ class GetSyncRoomIdsForUserEventShardTestCase(BaseMultiWorkerStreamTestCase):
|
|||
room_id3,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
class SortRoomsTestCase(HomeserverTestCase):
|
||||
"""
|
||||
Tests Sliding Sync handler `sort_rooms()` to make sure it sorts/orders rooms
|
||||
correctly.
|
||||
"""
|
||||
|
||||
servlets = [
|
||||
admin.register_servlets,
|
||||
knock.register_servlets,
|
||||
login.register_servlets,
|
||||
room.register_servlets,
|
||||
]
|
||||
|
||||
def default_config(self) -> JsonDict:
|
||||
config = super().default_config()
|
||||
# Enable sliding sync
|
||||
config["experimental_features"] = {"msc3575_enabled": True}
|
||||
return config
|
||||
|
||||
def prepare(self, reactor: MemoryReactor, clock: Clock, hs: HomeServer) -> None:
|
||||
self.sliding_sync_handler = self.hs.get_sliding_sync_handler()
|
||||
self.store = self.hs.get_datastores().main
|
||||
self.event_sources = hs.get_event_sources()
|
||||
|
||||
def test_sort_activity_basic(self) -> None:
|
||||
"""
|
||||
Rooms with newer activity are sorted first.
|
||||
"""
|
||||
user1_id = self.register_user("user1", "pass")
|
||||
user1_tok = self.login(user1_id, "pass")
|
||||
|
||||
room_id1 = self.helper.create_room_as(
|
||||
user1_id,
|
||||
tok=user1_tok,
|
||||
)
|
||||
room_id2 = self.helper.create_room_as(
|
||||
user1_id,
|
||||
tok=user1_tok,
|
||||
)
|
||||
|
||||
after_rooms_token = self.event_sources.get_current_token()
|
||||
|
||||
sync_room_map = self.get_success(
|
||||
self.sliding_sync_handler.get_sync_room_ids_for_user(
|
||||
UserID.from_string(user1_id),
|
||||
from_token=None,
|
||||
to_token=after_rooms_token,
|
||||
)
|
||||
)
|
||||
|
||||
sorted_room_info = self.get_success(
|
||||
self.sliding_sync_handler.sort_rooms(
|
||||
sync_room_map=sync_room_map,
|
||||
to_token=after_rooms_token,
|
||||
)
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
[room_id for room_id, _ in sorted_room_info],
|
||||
[room_id2, room_id1],
|
||||
)
|
||||
|
||||
# @parameterized.expand(
|
||||
# [
|
||||
# (Membership.INVITE,),
|
||||
# (Membership.KNOCK,),
|
||||
# (Membership.INVITE,),
|
||||
# ]
|
||||
# )
|
||||
def test_activity_after_invite(self) -> None:
|
||||
"""
|
||||
When someone is invited to a room, they shouldn't take anything into account after the invite.
|
||||
"""
|
||||
user1_id = self.register_user("user1", "pass")
|
||||
user1_tok = self.login(user1_id, "pass")
|
||||
user2_id = self.register_user("user2", "pass")
|
||||
user2_tok = self.login(user2_id, "pass")
|
||||
|
||||
before_rooms_token = self.event_sources.get_current_token()
|
||||
|
||||
# Create the rooms as user2 so we can have user1 with a clean slate to work from
|
||||
# and join in whatever order we need for the tests.
|
||||
room_id1 = self.helper.create_room_as(user2_id, tok=user2_tok, is_public=True)
|
||||
room_id2 = self.helper.create_room_as(user2_id, tok=user2_tok, is_public=True)
|
||||
room_id3 = self.helper.create_room_as(user2_id, tok=user2_tok, is_public=True)
|
||||
|
||||
# Here is the activity with user1 that will determine the sort of the rooms
|
||||
self.helper.join(room_id3, user1_id, tok=user1_tok)
|
||||
self.helper.invite(room_id1, src=user2_id, targ=user1_id, tok=user2_tok)
|
||||
self.helper.join(room_id2, user1_id, tok=user1_tok)
|
||||
|
||||
# Activity before the token but the user is only invited to this room so it
|
||||
# shouldn't be taken into account
|
||||
self.helper.send(room_id1, "activity in room1", tok=user2_tok)
|
||||
|
||||
after_rooms_token = self.event_sources.get_current_token()
|
||||
|
||||
# Activity after the token. Just make it in a different order than what we
|
||||
# expect to make sure we're not taking the activity after the token into
|
||||
# account.
|
||||
self.helper.send(room_id1, "activity in room1", tok=user2_tok)
|
||||
self.helper.send(room_id2, "activity in room2", tok=user2_tok)
|
||||
self.helper.send(room_id3, "activity in room3", tok=user2_tok)
|
||||
|
||||
# Get the rooms the user should be syncing with
|
||||
sync_room_map = self.get_success(
|
||||
self.sliding_sync_handler.get_sync_room_ids_for_user(
|
||||
UserID.from_string(user1_id),
|
||||
from_token=before_rooms_token,
|
||||
to_token=after_rooms_token,
|
||||
)
|
||||
)
|
||||
|
||||
# Sort the rooms (what we're testing)
|
||||
sorted_room_info = self.get_success(
|
||||
self.sliding_sync_handler.sort_rooms(
|
||||
sync_room_map=sync_room_map,
|
||||
to_token=after_rooms_token,
|
||||
)
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
[room_id for room_id, _ in sorted_room_info],
|
||||
[room_id2, room_id1, room_id3],
|
||||
"Corresponding map to disambiguate the opaque room IDs: "
|
||||
+ str(
|
||||
{
|
||||
"room_id1": room_id1,
|
||||
"room_id2": room_id2,
|
||||
"room_id3": room_id3,
|
||||
}
|
||||
),
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue