changeset 3624:fe9cb52f4a9c

tests: pubsub cache tests
author Goffi <goffi@goffi.org>
date Mon, 02 Aug 2021 21:52:17 +0200
parents 495184d00360
children 6559c0f847d4
files tests/unit/test_pubsub-cache.py
diffstat 1 files changed, 131 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/unit/test_pubsub-cache.py	Mon Aug 02 21:52:17 2021 +0200
@@ -0,0 +1,131 @@
+#!/usr/bin/env python3
+
+# Libervia: an XMPP client
+# Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org)
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+from twisted.internet import defer
+from pytest_twisted import ensureDeferred as ed
+from unittest.mock import MagicMock, patch
+from sat.memory.sqla import PubsubNode, SyncState
+from sat.core.constants import Const as C
+
+
+class TestPubsubCache:
+
+    @ed
+    async def test_cache_is_used_transparently(self, host, client):
+        """Cache is used when a pubsub getItems operation is done"""
+        items_ret = defer.Deferred()
+        items_ret.callback(([], {}))
+        client.pubsub_client.items = MagicMock(return_value=items_ret)
+        host.memory.storage.getPubsubNode.return_value = None
+        pubsub_node = host.memory.storage.setPubsubNode.return_value = PubsubNode(
+            sync_state = None
+        )
+        with patch.object(host.plugins["PUBSUB_CACHE"], "cacheNode") as cacheNode:
+            await host.plugins["XEP-0060"].getItems(
+                client,
+                None,
+                "urn:xmpp:microblog:0",
+            )
+            assert cacheNode.call_count == 1
+            assert cacheNode.call_args.args[-1] == pubsub_node
+
+    @ed
+    async def test_cache_is_skipped_with_use_cache_false(self, host, client):
+        """Cache is skipped when 'use_cache' extra field is False"""
+        items_ret = defer.Deferred()
+        items_ret.callback(([], {}))
+        client.pubsub_client.items = MagicMock(return_value=items_ret)
+        host.memory.storage.getPubsubNode.return_value = None
+        host.memory.storage.setPubsubNode.return_value = PubsubNode(
+            sync_state = None
+        )
+        with patch.object(host.plugins["PUBSUB_CACHE"], "cacheNode") as cacheNode:
+            await host.plugins["XEP-0060"].getItems(
+                client,
+                None,
+                "urn:xmpp:microblog:0",
+                extra = {C.KEY_USE_CACHE: False}
+            )
+            assert not cacheNode.called
+
+    @ed
+    async def test_cache_is_not_used_when_no_cache(self, host, client):
+        """Cache is skipped when 'pubsub_cache_strategy' is set to 'no_cache'"""
+        with host.use_option_and_reload(None, "pubsub_cache_strategy", "no_cache"):
+            items_ret = defer.Deferred()
+            items_ret.callback(([], {}))
+            client.pubsub_client.items = MagicMock(return_value=items_ret)
+            host.memory.storage.getPubsubNode.return_value = None
+            host.memory.storage.setPubsubNode.return_value = PubsubNode(
+                sync_state = None
+            )
+            with patch.object(host.plugins["PUBSUB_CACHE"], "cacheNode") as cacheNode:
+                await host.plugins["XEP-0060"].getItems(
+                    client,
+                    None,
+                    "urn:xmpp:microblog:0",
+                )
+                assert not cacheNode.called
+
+
+    @ed
+    async def test_no_pubsub_get_when_cache_completed(self, host, client):
+        """No pubsub get is emitted when items are fully cached"""
+        items_ret = defer.Deferred()
+        items_ret.callback(([], {}))
+        client.pubsub_client.items = MagicMock(return_value=items_ret)
+        host.memory.storage.getPubsubNode.return_value = PubsubNode(
+            sync_state = SyncState.COMPLETED
+        )
+        with patch.object(
+            host.plugins["PUBSUB_CACHE"],
+            "getItemsFromCache"
+        ) as getItemsFromCache:
+            getItemsFromCache.return_value = ([], {})
+            await host.plugins["XEP-0060"].getItems(
+                client,
+                None,
+                "urn:xmpp:microblog:0",
+            )
+            assert getItemsFromCache.call_count == 1
+            assert not client.pubsub_client.items.called
+
+    @ed
+    async def test_pubsub_get_when_cache_in_progress(self, host, client):
+        """Pubsub get is emitted when items are currently being cached"""
+        items_ret = defer.Deferred()
+        items_ret.callback(([], {}))
+        client.pubsub_client.items = MagicMock(return_value=items_ret)
+        host.memory.storage.getPubsubNode.return_value = PubsubNode(
+            sync_state = SyncState.IN_PROGRESS
+        )
+        with patch.object(host.plugins["PUBSUB_CACHE"], "analyseNode") as analyseNode:
+            analyseNode.return_value = {"to_sync": True}
+            with patch.object(
+                host.plugins["PUBSUB_CACHE"],
+                "getItemsFromCache"
+            ) as getItemsFromCache:
+                getItemsFromCache.return_value = ([], {})
+                assert client.pubsub_client.items.call_count == 0
+                await host.plugins["XEP-0060"].getItems(
+                    client,
+                    None,
+                    "urn:xmpp:microblog:0",
+                )
+                assert not getItemsFromCache.called
+                assert client.pubsub_client.items.call_count == 1