summary refs log tree commit diff
diff options
context:
space:
mode:
authorAndrew Morgan <1342360+anoadragon453@users.noreply.github.com>2021-05-21 17:29:14 +0100
committerGitHub <noreply@github.com>2021-05-21 17:29:14 +0100
commit21bd230831022a69ce90f334e869edd151155067 (patch)
treed5bfe348ffeb62773ae92a560ba14fd415d77d15
parentRemove unused properties from the SpaceSummaryHandler. (#10038) (diff)
downloadsynapse-21bd230831022a69ce90f334e869edd151155067.tar.xz
Add a test for update_presence (#10033)
https://github.com/matrix-org/synapse/issues/9962 uncovered that we accidentally removed all but one of the presence updates that we store in the database when persisting multiple updates. This could cause users' presence state to be stale.

The bug was fixed in #10014, and this PR just adds a test that failed on the old code, and was used to initially verify the bug.

The test attempts to insert some presence into the database in a batch using `PresenceStore.update_presence`, and then simply pulls it out again.
-rw-r--r--changelog.d/10033.bugfix1
-rw-r--r--tests/handlers/test_presence.py47
2 files changed, 47 insertions, 1 deletions
diff --git a/changelog.d/10033.bugfix b/changelog.d/10033.bugfix
new file mode 100644
index 0000000000..587d839b8c
--- /dev/null
+++ b/changelog.d/10033.bugfix
@@ -0,0 +1 @@
+Fixed deletion of new presence stream states from database.
\ No newline at end of file
diff --git a/tests/handlers/test_presence.py b/tests/handlers/test_presence.py
index 1ffab709fc..d90a9fec91 100644
--- a/tests/handlers/test_presence.py
+++ b/tests/handlers/test_presence.py
@@ -32,13 +32,19 @@ from synapse.handlers.presence import (
     handle_timeout,
     handle_update,
 )
+from synapse.rest import admin
 from synapse.rest.client.v1 import room
 from synapse.types import UserID, get_domain_from_id
 
 from tests import unittest
 
 
-class PresenceUpdateTestCase(unittest.TestCase):
+class PresenceUpdateTestCase(unittest.HomeserverTestCase):
+    servlets = [admin.register_servlets]
+
+    def prepare(self, reactor, clock, homeserver):
+        self.store = homeserver.get_datastore()
+
     def test_offline_to_online(self):
         wheel_timer = Mock()
         user_id = "@foo:bar"
@@ -292,6 +298,45 @@ class PresenceUpdateTestCase(unittest.TestCase):
             any_order=True,
         )
 
+    def test_persisting_presence_updates(self):
+        """Tests that the latest presence state for each user is persisted correctly"""
+        # Create some test users and presence states for them
+        presence_states = []
+        for i in range(5):
+            user_id = self.register_user(f"user_{i}", "password")
+
+            presence_state = UserPresenceState(
+                user_id=user_id,
+                state="online",
+                last_active_ts=1,
+                last_federation_update_ts=1,
+                last_user_sync_ts=1,
+                status_msg="I'm online!",
+                currently_active=True,
+            )
+            presence_states.append(presence_state)
+
+        # Persist these presence updates to the database
+        self.get_success(self.store.update_presence(presence_states))
+
+        # Check that each update is present in the database
+        db_presence_states = self.get_success(
+            self.store.get_all_presence_updates(
+                instance_name="master",
+                last_id=0,
+                current_id=len(presence_states) + 1,
+                limit=len(presence_states),
+            )
+        )
+
+        # Extract presence update user ID and state information into lists of tuples
+        db_presence_states = [(ps[0], ps[1]) for _, ps in db_presence_states[0]]
+        presence_states = [(ps.user_id, ps.state) for ps in presence_states]
+
+        # Compare what we put into the storage with what we got out.
+        # They should be identical.
+        self.assertEqual(presence_states, db_presence_states)
+
 
 class PresenceTimeoutTestCase(unittest.TestCase):
     def test_idle_timer(self):