|
23 | 23 | from synapse.handlers.sliding_sync import StateValues |
24 | 24 | from synapse.rest.client import knock, login, room, sync |
25 | 25 | from synapse.server import HomeServer |
| 26 | +from synapse.storage.databases.main.sliding_sync import LAZY_MEMBERS_UPDATE_INTERVAL_MS |
| 27 | +from synapse.types import SlidingSyncStreamToken |
26 | 28 | from synapse.util.clock import Clock |
| 29 | +from synapse.util.constants import MILLISECONDS_PER_SECOND |
27 | 30 |
|
28 | 31 | from tests.rest.client.sliding_sync.test_sliding_sync import SlidingSyncBase |
29 | 32 | from tests.test_utils.event_injection import mark_event_as_partial_state |
@@ -1932,3 +1935,129 @@ def test_rooms_required_state_expand_deduplicate(self) -> None: |
1932 | 1935 | # We should not see the room name again, as we have already sent that |
1933 | 1936 | # down. |
1934 | 1937 | self.assertIsNone(response_body["rooms"][room_id1].get("required_state")) |
| 1938 | + |
| 1939 | + def test_lazy_loaded_last_seen_ts(self) -> None: |
| 1940 | + """Test that the `last_seen_ts` column in |
| 1941 | + `sliding_sync_connection_lazy_members` is correctly kept up to date""" |
| 1942 | + |
| 1943 | + user1_id = self.register_user("user1", "pass") |
| 1944 | + user1_tok = self.login(user1_id, "pass") |
| 1945 | + user2_id = self.register_user("user2", "pass") |
| 1946 | + user2_tok = self.login(user2_id, "pass") |
| 1947 | + |
| 1948 | + room_id = self.helper.create_room_as(user2_id, tok=user2_tok, is_public=True) |
| 1949 | + self.helper.join(room_id, user1_id, tok=user1_tok) |
| 1950 | + |
| 1951 | + # Send a message so that user1 comes down sync. |
| 1952 | + self.helper.send(room_id, "msg", tok=user1_tok) |
| 1953 | + |
| 1954 | + sync_body = { |
| 1955 | + "lists": { |
| 1956 | + "foo-list": { |
| 1957 | + "ranges": [[0, 1]], |
| 1958 | + "required_state": [ |
| 1959 | + [EventTypes.Member, StateValues.LAZY], |
| 1960 | + ], |
| 1961 | + "timeline_limit": 1, |
| 1962 | + } |
| 1963 | + } |
| 1964 | + } |
| 1965 | + response_body, from_token = self.do_sync(sync_body, tok=user1_tok) |
| 1966 | + |
| 1967 | + # Check that user1 is returned |
| 1968 | + state_map = self.get_success( |
| 1969 | + self.storage_controllers.state.get_current_state(room_id) |
| 1970 | + ) |
| 1971 | + self._assertRequiredStateIncludes( |
| 1972 | + response_body["rooms"][room_id]["required_state"], |
| 1973 | + { |
| 1974 | + state_map[(EventTypes.Member, user1_id)], |
| 1975 | + }, |
| 1976 | + exact=True, |
| 1977 | + ) |
| 1978 | + |
| 1979 | + # Check that we have an entry in sliding_sync_connection_lazy_members |
| 1980 | + connection_pos1 = self.get_success( |
| 1981 | + SlidingSyncStreamToken.from_string(self.store, from_token) |
| 1982 | + ).connection_position |
| 1983 | + lazy_member_entries = self.get_success( |
| 1984 | + self.store.get_sliding_sync_connection_lazy_members( |
| 1985 | + connection_pos1, room_id, {user1_id} |
| 1986 | + ) |
| 1987 | + ) |
| 1988 | + self.assertIn(user1_id, lazy_member_entries) |
| 1989 | + |
| 1990 | + prev_timestamp = lazy_member_entries[user1_id] |
| 1991 | + |
| 1992 | + # If user1 is sent down again, the last_seen_ts should NOT be updated as |
| 1993 | + # not enough time has passed. |
| 1994 | + self.helper.send(room_id, "msg2", tok=user1_tok) |
| 1995 | + |
| 1996 | + response_body, from_token = self.do_sync( |
| 1997 | + sync_body, since=from_token, tok=user1_tok |
| 1998 | + ) |
| 1999 | + |
| 2000 | + # We expect the required_state map to be empty as nothing has changed. |
| 2001 | + state_map = self.get_success( |
| 2002 | + self.storage_controllers.state.get_current_state(room_id) |
| 2003 | + ) |
| 2004 | + self._assertRequiredStateIncludes( |
| 2005 | + response_body["rooms"][room_id].get("required_state", []), |
| 2006 | + {}, |
| 2007 | + exact=True, |
| 2008 | + ) |
| 2009 | + |
| 2010 | + connection_pos2 = self.get_success( |
| 2011 | + SlidingSyncStreamToken.from_string(self.store, from_token) |
| 2012 | + ).connection_position |
| 2013 | + |
| 2014 | + lazy_member_entries = self.get_success( |
| 2015 | + self.store.get_sliding_sync_connection_lazy_members( |
| 2016 | + connection_pos2, room_id, {user1_id} |
| 2017 | + ) |
| 2018 | + ) |
| 2019 | + |
| 2020 | + # The timestamp should be unchanged. |
| 2021 | + self.assertEqual(lazy_member_entries[user1_id], prev_timestamp) |
| 2022 | + |
| 2023 | + # Now advance the time by `LAZY_MEMBERS_UPDATE_INTERVAL_MS` so that we |
| 2024 | + # would update the timestamp. |
| 2025 | + self.reactor.advance(LAZY_MEMBERS_UPDATE_INTERVAL_MS / MILLISECONDS_PER_SECOND) |
| 2026 | + |
| 2027 | + # Send a message from user2 |
| 2028 | + self.helper.send(room_id, "msg3", tok=user2_tok) |
| 2029 | + |
| 2030 | + response_body, from_token = self.do_sync( |
| 2031 | + sync_body, since=from_token, tok=user1_tok |
| 2032 | + ) |
| 2033 | + |
| 2034 | + connection_pos3 = self.get_success( |
| 2035 | + SlidingSyncStreamToken.from_string(self.store, from_token) |
| 2036 | + ).connection_position |
| 2037 | + |
| 2038 | + lazy_member_entries = self.get_success( |
| 2039 | + self.store.get_sliding_sync_connection_lazy_members( |
| 2040 | + connection_pos3, room_id, {user1_id} |
| 2041 | + ) |
| 2042 | + ) |
| 2043 | + |
| 2044 | + # The timestamp for user1 should be unchanged, as they were not sent down. |
| 2045 | + self.assertEqual(lazy_member_entries[user1_id], prev_timestamp) |
| 2046 | + |
| 2047 | + # If user1 sends a message, then the timestamp should be updated. |
| 2048 | + self.helper.send(room_id, "msg4", tok=user1_tok) |
| 2049 | + |
| 2050 | + response_body, from_token = self.do_sync( |
| 2051 | + sync_body, since=from_token, tok=user1_tok |
| 2052 | + ) |
| 2053 | + connection_pos4 = self.get_success( |
| 2054 | + SlidingSyncStreamToken.from_string(self.store, from_token) |
| 2055 | + ).connection_position |
| 2056 | + |
| 2057 | + lazy_member_entries = self.get_success( |
| 2058 | + self.store.get_sliding_sync_connection_lazy_members( |
| 2059 | + connection_pos4, room_id, {user1_id} |
| 2060 | + ) |
| 2061 | + ) |
| 2062 | + # The timestamp for user1 should be updated. |
| 2063 | + self.assertGreater(lazy_member_entries[user1_id], prev_timestamp) |
0 commit comments