3624
+ − 1 #!/usr/bin/env python3
+ − 2
+ − 3 # Libervia: an XMPP client
+ − 4 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org)
+ − 5
+ − 6 # This program is free software: you can redistribute it and/or modify
+ − 7 # it under the terms of the GNU Affero General Public License as published by
+ − 8 # the Free Software Foundation, either version 3 of the License, or
+ − 9 # (at your option) any later version.
+ − 10
+ − 11 # This program is distributed in the hope that it will be useful,
+ − 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ − 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ − 14 # GNU Affero General Public License for more details.
+ − 15
+ − 16 # You should have received a copy of the GNU Affero General Public License
+ − 17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
+ − 18
+ − 19 from twisted.internet import defer
+ − 20 from pytest_twisted import ensureDeferred as ed
+ − 21 from unittest.mock import MagicMock , patch
+ − 22 from sat.memory.sqla import PubsubNode , SyncState
+ − 23 from sat.core.constants import Const as C
+ − 24
+ − 25
+ − 26 class TestPubsubCache :
+ − 27
+ − 28 @ed
+ − 29 async def test_cache_is_used_transparently ( self , host , client ):
+ − 30 """Cache is used when a pubsub getItems operation is done"""
+ − 31 items_ret = defer . Deferred ()
+ − 32 items_ret . callback (([], {}))
+ − 33 client . pubsub_client . items = MagicMock ( return_value = items_ret )
+ − 34 host . memory . storage . getPubsubNode . return_value = None
+ − 35 pubsub_node = host . memory . storage . setPubsubNode . return_value = PubsubNode (
+ − 36 sync_state = None
+ − 37 )
+ − 38 with patch . object ( host . plugins [ "PUBSUB_CACHE" ], "cacheNode" ) as cacheNode :
+ − 39 await host . plugins [ "XEP-0060" ] . getItems (
+ − 40 client ,
+ − 41 None ,
+ − 42 "urn:xmpp:microblog:0" ,
+ − 43 )
+ − 44 assert cacheNode . call_count == 1
+ − 45 assert cacheNode . call_args . args [ - 1 ] == pubsub_node
+ − 46
+ − 47 @ed
+ − 48 async def test_cache_is_skipped_with_use_cache_false ( self , host , client ):
+ − 49 """Cache is skipped when 'use_cache' extra field is False"""
+ − 50 items_ret = defer . Deferred ()
+ − 51 items_ret . callback (([], {}))
+ − 52 client . pubsub_client . items = MagicMock ( return_value = items_ret )
+ − 53 host . memory . storage . getPubsubNode . return_value = None
+ − 54 host . memory . storage . setPubsubNode . return_value = PubsubNode (
+ − 55 sync_state = None
+ − 56 )
+ − 57 with patch . object ( host . plugins [ "PUBSUB_CACHE" ], "cacheNode" ) as cacheNode :
+ − 58 await host . plugins [ "XEP-0060" ] . getItems (
+ − 59 client ,
+ − 60 None ,
+ − 61 "urn:xmpp:microblog:0" ,
+ − 62 extra = { C . KEY_USE_CACHE : False }
+ − 63 )
+ − 64 assert not cacheNode . called
+ − 65
+ − 66 @ed
+ − 67 async def test_cache_is_not_used_when_no_cache ( self , host , client ):
+ − 68 """Cache is skipped when 'pubsub_cache_strategy' is set to 'no_cache'"""
+ − 69 with host . use_option_and_reload ( None , "pubsub_cache_strategy" , "no_cache" ):
+ − 70 items_ret = defer . Deferred ()
+ − 71 items_ret . callback (([], {}))
+ − 72 client . pubsub_client . items = MagicMock ( return_value = items_ret )
+ − 73 host . memory . storage . getPubsubNode . return_value = None
+ − 74 host . memory . storage . setPubsubNode . return_value = PubsubNode (
+ − 75 sync_state = None
+ − 76 )
+ − 77 with patch . object ( host . plugins [ "PUBSUB_CACHE" ], "cacheNode" ) as cacheNode :
+ − 78 await host . plugins [ "XEP-0060" ] . getItems (
+ − 79 client ,
+ − 80 None ,
+ − 81 "urn:xmpp:microblog:0" ,
+ − 82 )
+ − 83 assert not cacheNode . called
+ − 84
+ − 85
+ − 86 @ed
+ − 87 async def test_no_pubsub_get_when_cache_completed ( self , host , client ):
+ − 88 """No pubsub get is emitted when items are fully cached"""
+ − 89 items_ret = defer . Deferred ()
+ − 90 items_ret . callback (([], {}))
+ − 91 client . pubsub_client . items = MagicMock ( return_value = items_ret )
+ − 92 host . memory . storage . getPubsubNode . return_value = PubsubNode (
+ − 93 sync_state = SyncState . COMPLETED
+ − 94 )
+ − 95 with patch . object (
+ − 96 host . plugins [ "PUBSUB_CACHE" ],
+ − 97 "getItemsFromCache"
+ − 98 ) as getItemsFromCache :
+ − 99 getItemsFromCache . return_value = ([], {})
+ − 100 await host . plugins [ "XEP-0060" ] . getItems (
+ − 101 client ,
+ − 102 None ,
+ − 103 "urn:xmpp:microblog:0" ,
+ − 104 )
+ − 105 assert getItemsFromCache . call_count == 1
+ − 106 assert not client . pubsub_client . items . called
+ − 107
+ − 108 @ed
+ − 109 async def test_pubsub_get_when_cache_in_progress ( self , host , client ):
+ − 110 """Pubsub get is emitted when items are currently being cached"""
+ − 111 items_ret = defer . Deferred ()
+ − 112 items_ret . callback (([], {}))
+ − 113 client . pubsub_client . items = MagicMock ( return_value = items_ret )
+ − 114 host . memory . storage . getPubsubNode . return_value = PubsubNode (
+ − 115 sync_state = SyncState . IN_PROGRESS
+ − 116 )
+ − 117 with patch . object ( host . plugins [ "PUBSUB_CACHE" ], "analyseNode" ) as analyseNode :
+ − 118 analyseNode . return_value = { "to_sync" : True }
+ − 119 with patch . object (
+ − 120 host . plugins [ "PUBSUB_CACHE" ],
+ − 121 "getItemsFromCache"
+ − 122 ) as getItemsFromCache :
+ − 123 getItemsFromCache . return_value = ([], {})
+ − 124 assert client . pubsub_client . items . call_count == 0
+ − 125 await host . plugins [ "XEP-0060" ] . getItems (
+ − 126 client ,
+ − 127 None ,
+ − 128 "urn:xmpp:microblog:0" ,
+ − 129 )
+ − 130 assert not getItemsFromCache . called
+ − 131 assert client . pubsub_client . items . call_count == 1