summary refs log tree commit diff
path: root/tests/rest/client/test_transactions.py
blob: d7cea302602eb598e7e42ecb6cff3bddc6656503 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
from synapse.rest.client.transactions import HttpTransactionCache
from synapse.rest.client.transactions import CLEANUP_PERIOD_MS
from twisted.internet import defer
from mock import Mock, call
from tests import unittest
from tests.utils import MockClock


class HttpTransactionCacheTestCase(unittest.TestCase):

    def setUp(self):
        self.clock = MockClock()
        self.cache = HttpTransactionCache(self.clock)

        self.mock_http_response = (200, "GOOD JOB!")
        self.mock_key = "foo"

    @defer.inlineCallbacks
    def test_executes_given_function(self):
        cb = Mock(
            return_value=defer.succeed(self.mock_http_response)
        )
        res = yield self.cache.fetch_or_execute(
            self.mock_key, cb, "some_arg", keyword="arg"
        )
        cb.assert_called_once_with("some_arg", keyword="arg")
        self.assertEqual(res, self.mock_http_response)

    @defer.inlineCallbacks
    def test_deduplicates_based_on_key(self):
        cb = Mock(
            return_value=defer.succeed(self.mock_http_response)
        )
        for i in range(3):  # invoke multiple times
            res = yield self.cache.fetch_or_execute(
                self.mock_key, cb, "some_arg", keyword="arg", changing_args=i
            )
            self.assertEqual(res, self.mock_http_response)
        # expect only a single call to do the work
        cb.assert_called_once_with("some_arg", keyword="arg", changing_args=0)

    @defer.inlineCallbacks
    def test_cleans_up(self):
        cb = Mock(
            return_value=defer.succeed(self.mock_http_response)
        )
        yield self.cache.fetch_or_execute(
            self.mock_key, cb, "an arg"
        )
        # should NOT have cleaned up yet
        self.clock.advance_time_msec(CLEANUP_PERIOD_MS / 2)

        yield self.cache.fetch_or_execute(
            self.mock_key, cb, "an arg"
        )
        # still using cache
        cb.assert_called_once_with("an arg")

        self.clock.advance_time_msec(CLEANUP_PERIOD_MS)

        yield self.cache.fetch_or_execute(
            self.mock_key, cb, "an arg"
        )
        # no longer using cache
        self.assertEqual(cb.call_count, 2)
        self.assertEqual(
            cb.call_args_list,
            [call("an arg",), call("an arg",)]
        )