|
1 |
| - |
2 | 1 | import pytest
|
| 2 | +import sys |
3 | 3 | from unittest.mock import (
|
4 | 4 | Mock,
|
5 | 5 | patch,
|
6 | 6 | )
|
7 | 7 |
|
| 8 | +import pytest_asyncio |
| 9 | + |
8 | 10 | from web3.datastructures import (
|
9 | 11 | AttributeDict,
|
10 | 12 | )
|
|
14 | 16 | from web3.middleware.stalecheck import (
|
15 | 17 | StaleBlockchain,
|
16 | 18 | _is_fresh,
|
| 19 | + async_make_stalecheck_middleware, |
17 | 20 | )
|
18 | 21 |
|
19 | 22 |
|
@@ -120,3 +123,95 @@ def test_stalecheck_adds_block_to_cache(request_middleware, allowable_delay):
|
120 | 123 | request_middleware('', [])
|
121 | 124 | assert fresh_spy.call_count == 3
|
122 | 125 | assert fresh_spy.call_args == ((block, allowable_delay), )
|
| 126 | + |
| 127 | + |
| 128 | +# -- async -- # |
| 129 | + |
| 130 | + |
| 131 | +min_version = pytest.mark.skipif( |
| 132 | + sys.version_info < (3, 8), |
| 133 | + reason="AsyncMock requires python3.8 or higher" |
| 134 | +) |
| 135 | + |
| 136 | + |
| 137 | +@pytest_asyncio.fixture(scope="session") |
| 138 | +async def request_async_middleware(allowable_delay): |
| 139 | + from unittest.mock import AsyncMock |
| 140 | + middleware = await async_make_stalecheck_middleware(allowable_delay) |
| 141 | + make_request, web3 = AsyncMock(), AsyncMock() |
| 142 | + initialized = await middleware(make_request, web3) |
| 143 | + # for easier mocking, later: |
| 144 | + initialized.web3 = web3 |
| 145 | + initialized.make_request = make_request |
| 146 | + return initialized |
| 147 | + |
| 148 | + |
| 149 | +@pytest.mark.asyncio |
| 150 | +@min_version |
| 151 | +async def test_async_stalecheck_pass(request_async_middleware): |
| 152 | + with patch("web3.middleware.stalecheck._is_fresh", return_value=True): |
| 153 | + method, params = object(), object() |
| 154 | + await request_async_middleware(method, params) |
| 155 | + request_async_middleware.make_request.assert_called_once_with(method, params) |
| 156 | + |
| 157 | + |
| 158 | +@pytest.mark.asyncio |
| 159 | +@min_version |
| 160 | +async def test_async_stalecheck_fail(request_async_middleware, now): |
| 161 | + with patch("web3.middleware.stalecheck._is_fresh", return_value=False): |
| 162 | + request_async_middleware.web3.eth.get_block.return_value = stub_block(now) |
| 163 | + with pytest.raises(StaleBlockchain): |
| 164 | + await request_async_middleware("", []) |
| 165 | + |
| 166 | + |
| 167 | +@pytest.mark.asyncio |
| 168 | +@pytest.mark.parametrize("rpc_method", ["eth_getBlockByNumber"]) |
| 169 | +@min_version |
| 170 | +async def test_async_stalecheck_ignores_get_by_block_methods( |
| 171 | + request_async_middleware, rpc_method |
| 172 | +): |
| 173 | + # This is especially critical for get_block("latest") which would cause |
| 174 | + # infinite recursion |
| 175 | + with patch("web3.middleware.stalecheck._is_fresh", side_effect=[False, True]): |
| 176 | + await request_async_middleware(rpc_method, []) |
| 177 | + assert not request_async_middleware.web3.eth.get_block.called |
| 178 | + |
| 179 | + |
| 180 | +@pytest.mark.asyncio |
| 181 | +@min_version |
| 182 | +async def test_async_stalecheck_calls_is_fresh_with_empty_cache( |
| 183 | + request_async_middleware, allowable_delay |
| 184 | +): |
| 185 | + with patch( |
| 186 | + "web3.middleware.stalecheck._is_fresh", side_effect=[False, True] |
| 187 | + ) as fresh_spy: |
| 188 | + block = object() |
| 189 | + request_async_middleware.web3.eth.get_block.return_value = block |
| 190 | + await request_async_middleware("", []) |
| 191 | + cache_call, live_call = fresh_spy.call_args_list |
| 192 | + assert cache_call[0] == (None, allowable_delay) |
| 193 | + assert live_call[0] == (block, allowable_delay) |
| 194 | + |
| 195 | + |
| 196 | +@pytest.mark.asyncio |
| 197 | +@min_version |
| 198 | +async def test_async_stalecheck_adds_block_to_cache( |
| 199 | + request_async_middleware, allowable_delay |
| 200 | +): |
| 201 | + with patch( |
| 202 | + "web3.middleware.stalecheck._is_fresh", side_effect=[False, True, True] |
| 203 | + ) as fresh_spy: |
| 204 | + block = object() |
| 205 | + request_async_middleware.web3.eth.get_block.return_value = block |
| 206 | + |
| 207 | + # cache miss |
| 208 | + await request_async_middleware("", []) |
| 209 | + cache_call, live_call = fresh_spy.call_args_list |
| 210 | + assert fresh_spy.call_count == 2 |
| 211 | + assert cache_call == ((None, allowable_delay), ) |
| 212 | + assert live_call == ((block, allowable_delay), ) |
| 213 | + |
| 214 | + # cache hit |
| 215 | + await request_async_middleware("", []) |
| 216 | + assert fresh_spy.call_count == 3 |
| 217 | + assert fresh_spy.call_args == ((block, allowable_delay), ) |
0 commit comments